You've already forked qBittorrent
mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-11-07 01:22:30 +01:00
Compare commits
136 Commits
release-2.
...
release-2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c79537176 | ||
|
|
2b45e1baa3 | ||
|
|
476b395166 | ||
|
|
7157996dc2 | ||
|
|
218f386502 | ||
|
|
b492051d32 | ||
|
|
39c7d884c9 | ||
|
|
4d2d0bf08d | ||
|
|
34c1fd759b | ||
|
|
922aebec9a | ||
|
|
4d39b3accd | ||
|
|
c713bd56e0 | ||
|
|
efcd652e3d | ||
|
|
8d6df1f15f | ||
|
|
ca835a105b | ||
|
|
2de1a7cc30 | ||
|
|
3de83319a8 | ||
|
|
cfc75905a2 | ||
|
|
2c30d5a1ca | ||
|
|
d162d0c3c6 | ||
|
|
509eb9bcf0 | ||
|
|
1766877605 | ||
|
|
fa78fba559 | ||
|
|
44ff7161aa | ||
|
|
96837a3658 | ||
|
|
e4d93a96e7 | ||
|
|
ccb2ed9a69 | ||
|
|
ae5693544d | ||
|
|
3a72c11e39 | ||
|
|
4176abd18a | ||
|
|
cba36fcb14 | ||
|
|
9f33656e61 | ||
|
|
a4123a6462 | ||
|
|
313b2630bd | ||
|
|
87b0ae9a79 | ||
|
|
81778a0090 | ||
|
|
5d0d63d89a | ||
|
|
764e8a365b | ||
|
|
e302042520 | ||
|
|
e453eb9a91 | ||
|
|
98fcb91dae | ||
|
|
c8a1f625f0 | ||
|
|
b70cf7c049 | ||
|
|
ecdfe63d00 | ||
|
|
7635fe51f7 | ||
|
|
8cba38ac62 | ||
|
|
fab63e6ffc | ||
|
|
27f257ba03 | ||
|
|
a2aa462030 | ||
|
|
0f44804225 | ||
|
|
de78fc495b | ||
|
|
93731f1b3f | ||
|
|
2e9e10299c | ||
|
|
9f627b5ec9 | ||
|
|
ad252f432a | ||
|
|
eb1feddea6 | ||
|
|
1634014dde | ||
|
|
e863772159 | ||
|
|
7c34f4e93c | ||
|
|
91032056e1 | ||
|
|
f427d267b6 | ||
|
|
a7a8265053 | ||
|
|
827fceca83 | ||
|
|
7aaa3e8f51 | ||
|
|
1fe49198d1 | ||
|
|
c582aff563 | ||
|
|
5272f1cba3 | ||
|
|
b72d356083 | ||
|
|
fbd6533eee | ||
|
|
2998dbd0a1 | ||
|
|
cb8da634f4 | ||
|
|
e8f229816e | ||
|
|
fe0fc952e8 | ||
|
|
29a76ae600 | ||
|
|
5471600dfb | ||
|
|
df42c4d59f | ||
|
|
8047495b2e | ||
|
|
de04b47c29 | ||
|
|
b709bec24d | ||
|
|
35f93e8e16 | ||
|
|
554a84f8b0 | ||
|
|
f26fcabde1 | ||
|
|
75b91c204d | ||
|
|
0837c25602 | ||
|
|
34f8937b8d | ||
|
|
4a7f3ee415 | ||
|
|
b218531ff7 | ||
|
|
e96dee2038 | ||
|
|
080105c088 | ||
|
|
5d2535c1c1 | ||
|
|
49b21059fa | ||
|
|
c1af948649 | ||
|
|
36ad3df9e7 | ||
|
|
e607d721a2 | ||
|
|
5bfbfeb665 | ||
|
|
1f1eabb1e9 | ||
|
|
762050f8fc | ||
|
|
e3c1270205 | ||
|
|
414685910b | ||
|
|
d61b9c5d4d | ||
|
|
cf86a1cecd | ||
|
|
a3f3287e24 | ||
|
|
6e18d780ba | ||
|
|
7dde763fc6 | ||
|
|
8c85ffca5f | ||
|
|
321e568d86 | ||
|
|
e0649a7e78 | ||
|
|
4cd3233cd0 | ||
|
|
c554528afe | ||
|
|
7ab7f4b0fc | ||
|
|
58c0ac7638 | ||
|
|
2514224a3a | ||
|
|
247f6b4a8e | ||
|
|
3d89864b75 | ||
|
|
7ac75ad772 | ||
|
|
caa628371f | ||
|
|
fd31f632d9 | ||
|
|
a25b6e087b | ||
|
|
1626d938d1 | ||
|
|
a4c7640499 | ||
|
|
2c1b93a12b | ||
|
|
8f19025c2a | ||
|
|
20d41bcff2 | ||
|
|
1ad77e00ff | ||
|
|
0b65c02666 | ||
|
|
294095367a | ||
|
|
05a6ffd554 | ||
|
|
e0a30dc40c | ||
|
|
1940bc4e73 | ||
|
|
a7e4e0273a | ||
|
|
29a9d57cdc | ||
|
|
9c7a4e4983 | ||
|
|
35ead5bcf2 | ||
|
|
645bd58d79 | ||
|
|
6c47a552ab | ||
|
|
f54bc8bea4 |
2
AUTHORS
2
AUTHORS
@@ -83,7 +83,7 @@ Translations authors:
|
||||
- German: Niels Hoffmann (zentralmaschine@users.sourceforge.net)
|
||||
- Greek: Tsvetan Bankov (emerge_life@users.sourceforge.net) and Stephanos Antaris (santaris@csd.auth.gr)
|
||||
- Hungarian: Majoros Péter (majoros.j.p@t-online.hu)
|
||||
- Italian: Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)
|
||||
- Italian: Matteo Sechi (bu17714@gmail.com)
|
||||
- Japanese: Nardog (alphisation@gmail.com)
|
||||
- Korean: Jin Woo Sin (jin828sin@users.sourceforge.net)
|
||||
- Norwegian: Lars-Erik Labori (hamil@users.sourceforge.net)
|
||||
|
||||
101
Changelog
101
Changelog
@@ -1,8 +1,99 @@
|
||||
* 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 transfer list column to display the current tracker
|
||||
- COSMETIC: Replaced message box by on-screen notification for download errors
|
||||
* Unreleased - Christophe Dumez <chris@qbittorrent.org> - v2.4.11
|
||||
- BUGFIX: Do not report a progress of 100% in the Web UI unless the
|
||||
torrent is really complete (closes #674349)
|
||||
- BUGFIX: Fix possible incorrect behavior with queueing
|
||||
- BUGFIX: Fix RSS refresh interval saving
|
||||
- BUGFIX: Fix possible crash when setting RSS proxy (closes #676288)
|
||||
- BUGFIX: Fix HTTP redirect issue that would cause the torrent addition to
|
||||
show up for automated RSS downloads (Closes #677565)
|
||||
|
||||
* Wed Nov 10 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.10
|
||||
- BUGFIX: Fix possible crash when selecting a RSS item (really closes #575624)
|
||||
- BUGFIX: Improved IPv6 support (IP filter and Peer list)
|
||||
- BUGFIX: Make IP filter more tolerant towards strangely formatted IPs
|
||||
- BUGFIX: More reliable folder scanning
|
||||
- BUGFIX: Do not create the torrent root folder at final destination if
|
||||
torrent is in the temp dir (closes #673271)
|
||||
- BUGFIX: Fix compilation with libnotify v0.7.0 (closes #671769)
|
||||
- BUGFIX: Use a pointing cursor over status bar buttons
|
||||
|
||||
* Sun Oct 31 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.9
|
||||
- BUGFIX: Fix crash when pressing enter in save path field in torrent addition dialog
|
||||
- BUGFIX: Fix crash when deleting a torrent with no metadata (closes #667528)
|
||||
- BUGFIX: Fix possible crash on clicking a RSS article (closes #575624)
|
||||
- BUGFIX: Correctly update total number of torrents when a torrent is automatically removed (closes #668726)
|
||||
- BUGFIX: Correctly display the hash of torrents with no metadata
|
||||
- BUGFIX: Elide status bar text if it is too wide
|
||||
- BUGFIX: Make sure the splash screen is displayed for 2 seconds
|
||||
- BUGFIX: Make listening on a particular interface more reliable
|
||||
- BUGFIX: Fix torrent size update in torrent addition dialog
|
||||
- BUGFIX: Fix possible crash on qBittorrent shutdown
|
||||
- BUGFIX: Fix and improve file priorities editing (closes #669084)
|
||||
- I18N: Updated Arabic, Italian and Croatian translations
|
||||
|
||||
* Sun Oct 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.8
|
||||
- BUGFIX: Fix possible crash on manual peer ban
|
||||
- BUGFIX: Improved hostname resolution code
|
||||
- BUGFIX: Several search plugins fixed
|
||||
- BUGFIX: Auto-disable the shutdown feature
|
||||
- BUGFIX: Remember the current property tab on startup
|
||||
- BUGFIX: Fix status list widget height issue on style change
|
||||
- BUGFIX: Fix rounding issue in torrent progress display
|
||||
- BUGFIX: Fix issue when altering files priorities of a seeding torrent
|
||||
- BUGFIX: Better fix for save path editing issues in torrent addition dialog
|
||||
- BUGFIX: Peers can now be sorted by country
|
||||
|
||||
* Tue Oct 19 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.7
|
||||
- BUGFIX: Display the priority column when the queueing system gets enabled
|
||||
- BUGFIX: Fix encoding problem in file renaming
|
||||
- BUGFIX: Delete uneeded files on torrent "soft" deletion
|
||||
- BUGFIX: Fix issues when marking a file as 'not downloaded' causes the torrent to complete
|
||||
- BUGFIX: Improved "Set Location" and "Change save path" dialogs
|
||||
- BUGFIX: Fix display of queued seeding torrents
|
||||
|
||||
* Sun Oct 17 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.6
|
||||
- BUGFIX: Fix "torrent seeding after creation" feature
|
||||
- BUGFIX: The properties panel data would sometimes not match the selected torrent
|
||||
- BUGFIX: Fix detection of files at final destination when temp dir is used
|
||||
- BUGFIX: Fix moving of a torrent to an unexisting directory
|
||||
|
||||
* Tue Oct 12 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.5
|
||||
- BUGFIX: Remember torrent completion date correctly
|
||||
- BUGFIX: Fix feature to keep incomplete torrents in a separate folder
|
||||
- BUGFIX: Fix display of URL seeds in the UI
|
||||
- BUGFIX: Improved peer hostname resolution with caching
|
||||
- BUGFIX: Piece availability/downloaded widgets performance improvement
|
||||
|
||||
* Fri Oct 1 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.4
|
||||
- BUGFIX: Clean program exit on system shutdown/logout
|
||||
- BUGFIX: Fix possible search engine plugin update
|
||||
|
||||
* Tue Sep 28 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.3
|
||||
- BUGFIX: Fix encoding issue in command line parameters processing
|
||||
- BUGFIX: Fix possible crash when changing the save path in addition dialog
|
||||
- BUGFIX: Fix wrong mapping to source model
|
||||
|
||||
* Sun Sep 26 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.2
|
||||
- BUGFIX: Fix display of torrent content in addition dialog
|
||||
- BUGFIX: Really fix manual editing of save path in torrent addition dialog
|
||||
|
||||
* Sun Sep 26 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.1
|
||||
- I18N: Updated Arabic translation
|
||||
- I18N: Fixes to German translation
|
||||
- BUGFIX: Save path can now be edited in torrent addition dialog
|
||||
- BUGFIX: Fix save path encoding on non-utf8 systems
|
||||
- BUGFIX: Fix saving to drive root on Windows
|
||||
- BUGFIX: OGV can now be previewed
|
||||
- BUGFIX: Maximum download limit is now 10MB/s
|
||||
- BUGFIX: Fix 'download in scan dir' persistence
|
||||
- BUGFIX: Add .torrent extension only when missing (torrent creator)
|
||||
- BUGFIX: Fix possible issue with temporary download path persistence
|
||||
- BUGFIX: Added support for | (OR) operator in RSS feed downloader
|
||||
- BUGFIX: Fix Web UI for spanish users
|
||||
- BUGFIX: Fix locale switching from Web UI
|
||||
- BUGFIX: Use AND operator for torrentdownloads.net searches
|
||||
- BUGFIX: Limit torrent addition dialog width to fit the screen
|
||||
- COSMETIC: Fix progress bars style on Windows
|
||||
|
||||
* Tue Aug 24 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.4.0
|
||||
- FEATURE: Added actions to "Move to top/bottom" of priority queue
|
||||
|
||||
2
INSTALL
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.5.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||
- Qt >= 4.4.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
|
||||
|
||||
- pkg-config executable
|
||||
|
||||
|
||||
8
configure
vendored
8
configure
vendored
@@ -325,7 +325,7 @@ cat >$1/modules.cpp <<EOT
|
||||
#line 1 "qt4.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: Qt >= 4.5
|
||||
name: Qt >= 4.4
|
||||
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.5"; }
|
||||
QString shortname() const { return "Qt 4.5"; }
|
||||
QString name() const { return "Qt >= 4.4"; }
|
||||
QString shortname() const { return "Qt 4.4"; }
|
||||
bool exec()
|
||||
{
|
||||
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||
conf->addDefine("DISABLE_GUI");
|
||||
}
|
||||
return(QT_VERSION >= 0x040500);
|
||||
return(QT_VERSION >= 0x040400);
|
||||
}
|
||||
};
|
||||
#line 1 "pkg-config.qcm"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: Qt >= 4.5
|
||||
name: Qt >= 4.4
|
||||
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.5"; }
|
||||
QString shortname() const { return "Qt 4.5"; }
|
||||
QString name() const { return "Qt >= 4.4"; }
|
||||
QString shortname() const { return "Qt 4.4"; }
|
||||
bool exec()
|
||||
{
|
||||
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||
conf->addDefine("DISABLE_GUI");
|
||||
}
|
||||
return(QT_VERSION >= 0x040500);
|
||||
return(QT_VERSION >= 0x040400);
|
||||
}
|
||||
};
|
||||
|
||||
46
src/GUI.cpp
46
src/GUI.cpp
@@ -52,7 +52,7 @@
|
||||
#include "torrentadditiondlg.h"
|
||||
#include "searchengine.h"
|
||||
#include "rss_imp.h"
|
||||
#include "qbtsession.h"
|
||||
#include "bittorrent.h"
|
||||
#include "about_imp.h"
|
||||
#include "trackerlogin.h"
|
||||
#include "options_imp.h"
|
||||
@@ -126,7 +126,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
|
||||
// Fix Tool bar layout
|
||||
toolBar->layout()->setSpacing(7);
|
||||
// Creating Bittorrent session
|
||||
BTSession = new QBtSession();
|
||||
BTSession = new Bittorrent();
|
||||
connect(BTSession, SIGNAL(fullDiskError(QTorrentHandle&, QString)), this, SLOT(fullDiskError(QTorrentHandle&, QString)));
|
||||
connect(BTSession, SIGNAL(finishedTorrent(QTorrentHandle&)), this, SLOT(finishedTorrent(QTorrentHandle&)));
|
||||
connect(BTSession, SIGNAL(trackerAuthenticationRequired(QTorrentHandle&)), this, SLOT(trackerAuthenticationRequired(QTorrentHandle&)));
|
||||
@@ -202,7 +202,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
|
||||
displaySearchTab(actionSearch_engine->isChecked());
|
||||
displayRSSTab(actionRSS_Reader->isChecked());
|
||||
actionShutdown_when_downloads_complete->setChecked(Preferences::shutdownWhenDownloadsComplete());
|
||||
actionShutdown_qBittorrent_when_downloads_complete->setChecked(Preferences::shutdownqBTWhenDownloadsComplete());
|
||||
|
||||
show();
|
||||
|
||||
@@ -211,13 +210,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
|
||||
properties->readSettings();
|
||||
|
||||
// Limit status filters list height
|
||||
int cur_height = 80;
|
||||
do {
|
||||
transferListFilters->getStatusFilters()->setFixedHeight(cur_height);
|
||||
cur_height += 10;
|
||||
transferListFilters->getStatusFilters()->scrollToBottom();
|
||||
}while(transferListFilters->getStatusFilters()->verticalScrollBar()->sliderPosition() > 0);
|
||||
transferListFilters->getStatusFilters()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
transferListFilters->getStatusFilters()->updateHeight();
|
||||
|
||||
if(ui_locked) {
|
||||
hide();
|
||||
@@ -542,7 +535,7 @@ void GUI::askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h) {
|
||||
|
||||
void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{
|
||||
// Display a message box
|
||||
showNotificationBaloon(tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason));
|
||||
QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason));
|
||||
}
|
||||
|
||||
void GUI::on_actionSet_global_upload_limit_triggered() {
|
||||
@@ -922,6 +915,7 @@ void GUI::optionsSaved() {
|
||||
// Load program preferences
|
||||
void GUI::loadPreferences(bool configure_session) {
|
||||
BTSession->addConsoleMessage(tr("Options were saved successfully."));
|
||||
#ifndef Q_WS_MAC
|
||||
const bool newSystrayIntegration = Preferences::systrayIntegration();
|
||||
actionLock_qBittorrent->setEnabled(newSystrayIntegration);
|
||||
if(newSystrayIntegration != (systrayIcon!=0)) {
|
||||
@@ -946,6 +940,7 @@ void GUI::loadPreferences(bool configure_session) {
|
||||
delete myTrayIconMenu;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// General
|
||||
if(Preferences::isToolbarDisplayed()) {
|
||||
toolBar->setVisible(true);
|
||||
@@ -963,7 +958,7 @@ void GUI::loadPreferences(bool configure_session) {
|
||||
properties->getPeerList()->setAlternatingRowColors(Preferences::useAlternatingRowColors());
|
||||
// Queueing System
|
||||
if(Preferences::isQueueingSystemEnabled()) {
|
||||
if(!configure_session || !BTSession->isQueueingEnabled()) {
|
||||
if(!actionDecreasePriority->isVisible()) {
|
||||
transferList->hidePriorityColumn(false);
|
||||
actionDecreasePriority->setVisible(true);
|
||||
actionIncreasePriority->setVisible(true);
|
||||
@@ -972,7 +967,7 @@ void GUI::loadPreferences(bool configure_session) {
|
||||
toolBar->layout()->setSpacing(7);
|
||||
}
|
||||
} else {
|
||||
if(BTSession->isQueueingEnabled()) {
|
||||
if(actionDecreasePriority->isVisible()) {
|
||||
transferList->hidePriorityColumn(true);
|
||||
actionDecreasePriority->setVisible(false);
|
||||
actionIncreasePriority->setVisible(false);
|
||||
@@ -1009,8 +1004,9 @@ void GUI::trackerAuthenticationRequired(QTorrentHandle& h) {
|
||||
// Check connection status and display right icon
|
||||
void GUI::updateGUI() {
|
||||
// update global informations
|
||||
#ifndef Q_WS_MAC
|
||||
if(systrayIcon) {
|
||||
#if defined(Q_WS_X11) || defined(Q_WS_MAC)
|
||||
#if defined(Q_WS_X11)
|
||||
QString html = "<div style='background-color: #678db2; color: #fff;height: 18px; font-weight: bold; margin-bottom: 5px;'>";
|
||||
html += tr("qBittorrent");
|
||||
html += "</div>";
|
||||
@@ -1028,6 +1024,7 @@ void GUI::updateGUI() {
|
||||
#endif
|
||||
systrayIcon->setToolTip(html); // tray icon
|
||||
}
|
||||
#endif
|
||||
if(displaySpeedInTitle) {
|
||||
setWindowTitle(tr("qBittorrent %1 (Down: %2/s, Up: %3/s)", "%1 is qBittorrent version").arg(QString::fromUtf8(VERSION)).arg(misc::friendlyUnit(BTSession->getSessionStatus().payload_download_rate)).arg(misc::friendlyUnit(BTSession->getSessionStatus().payload_upload_rate)));
|
||||
}
|
||||
@@ -1038,7 +1035,12 @@ void GUI::showNotificationBaloon(QString title, QString msg) const {
|
||||
#ifdef WITH_LIBNOTIFY
|
||||
if (notify_init ("summary-body")) {
|
||||
NotifyNotification* notification;
|
||||
notification = notify_notification_new (qPrintable(title), qPrintable(msg), "qbittorrent", 0);
|
||||
|
||||
notification = notify_notification_new (qPrintable(title), qPrintable(msg), "qbittorrent"
|
||||
#if !defined(NOTIFY_VERSION_MINOR) || (NOTIFY_VERSION_MAJOR == 0 && NOTIFY_VERSION_MINOR < 7)
|
||||
, 0
|
||||
#endif
|
||||
);
|
||||
gboolean success = notify_notification_show (notification, NULL);
|
||||
g_object_unref(G_OBJECT(notification));
|
||||
notify_uninit ();
|
||||
@@ -1047,8 +1049,10 @@ void GUI::showNotificationBaloon(QString title, QString msg) const {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef Q_WS_MAC
|
||||
if(systrayIcon && QSystemTrayIcon::supportsMessages())
|
||||
systrayIcon->showMessage(title, msg, QSystemTrayIcon::Information, TIME_TRAY_BALLOON);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
@@ -1085,6 +1089,7 @@ void GUI::downloadFromURLList(const QStringList& url_list) {
|
||||
*****************************************************/
|
||||
|
||||
void GUI::createSystrayDelayed() {
|
||||
#ifndef Q_WS_MAC
|
||||
static int timeout = 20;
|
||||
if(QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
// Ok, systray integration is now supported
|
||||
@@ -1105,6 +1110,7 @@ void GUI::createSystrayDelayed() {
|
||||
Preferences::setSystrayIntegration(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GUI::updateAltSpeedsBtn(bool alternative) {
|
||||
@@ -1171,11 +1177,6 @@ void GUI::on_actionShutdown_when_downloads_complete_triggered() {
|
||||
Preferences::setShutdownWhenDownloadsComplete(is_checked);
|
||||
}
|
||||
|
||||
void GUI::on_actionShutdown_qBittorrent_when_downloads_complete_triggered() {
|
||||
bool is_checked = static_cast<QAction*>(sender())->isChecked();
|
||||
Preferences::setShutdownqBTWhenDownloadsComplete(is_checked);
|
||||
}
|
||||
|
||||
void GUI::on_actionSpeed_in_title_bar_triggered() {
|
||||
displaySpeedInTitle = static_cast<QAction*>(sender())->isChecked();
|
||||
Preferences::showSpeedInTitleBar(displaySpeedInTitle);
|
||||
@@ -1210,3 +1211,8 @@ void GUI::on_actionDownload_from_URL_triggered() {
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::on_actionDonate_money_triggered()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl("http://sourceforge.net/donate/index.php?group_id=163414"));
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "ui_mainwindow.h"
|
||||
#include "qtorrenthandle.h"
|
||||
|
||||
class QBtSession;
|
||||
class Bittorrent;
|
||||
class QTimer;
|
||||
class downloadFromURL;
|
||||
class SearchEngine;
|
||||
@@ -140,7 +140,7 @@ protected:
|
||||
private:
|
||||
QFileSystemWatcher *executable_watcher;
|
||||
// Bittorrent
|
||||
QBtSession *BTSession;
|
||||
Bittorrent *BTSession;
|
||||
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; // Still needed?
|
||||
// GUI related
|
||||
QTimer *guiUpdater;
|
||||
@@ -183,7 +183,7 @@ private slots:
|
||||
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_actionDonate_money_triggered();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
BIN
src/Icons/oxygen/emblem-favorite.png
Normal file
BIN
src/Icons/oxygen/emblem-favorite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@@ -1,6 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Categories=Qt;Network;P2P;
|
||||
Comment=V2.5.0
|
||||
Comment=V2.4.11
|
||||
Exec=qbittorrent %f
|
||||
GenericName=Bittorrent client
|
||||
GenericName[ar]=العميل Bittorrent
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 75 KiB |
@@ -47,7 +47,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>2.5.0</string>
|
||||
<string>2.4.11</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
||||
@@ -73,7 +73,7 @@ class about : public QDialog, private Ui::AboutDlg{
|
||||
<li><u>German:</u> Niels Hoffmann (zentralmaschine@users.sourceforge.net)</li>\
|
||||
<li><u>Greek:</u> Tsvetan Bankov (emerge_life@users.sourceforge.net)</li>\
|
||||
<li><u>Hungarian:</u> Majoros Péter (majoros.peterj@gmail.com)</li>\
|
||||
<li><u>Italian:</u> Mirko Ferrari (mirkoferrari@gmail.com) and Ferraro Luciano (luciano.ferraro@gmail.com)</li>\
|
||||
<li><u>Italian:</u> Matteo Sechi (bu17714@gmail.com)</li>\
|
||||
<li><u>Japanese:</u> Nardog (alphisation@gmail.com)</li>\
|
||||
<li><u>Korean:</u> Jin Woo Sin (jin828sin@users.sourceforge.net)</li>\
|
||||
<li><u>Norwegian:</u> Lars-Erik Labori (hamil@users.sourceforge.net)</li>\
|
||||
|
||||
@@ -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, PROGRAM_NOTIFICATIONS, TRACKER_STATUS, TRACKER_PORT };
|
||||
#define ROW_COUNT 15
|
||||
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 };
|
||||
#define ROW_COUNT 13
|
||||
|
||||
class AdvancedSettings: public QTableWidget {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
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;
|
||||
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, *cb_program_notifications;
|
||||
QComboBox *combo_iface;
|
||||
|
||||
public:
|
||||
@@ -53,8 +53,6 @@ public:
|
||||
delete cb_super_seeding;
|
||||
delete combo_iface;
|
||||
delete cb_program_notifications;
|
||||
delete spin_tracker_port;
|
||||
delete cb_tracker_status;
|
||||
}
|
||||
|
||||
public slots:
|
||||
@@ -90,9 +88,6 @@ public slots:
|
||||
}
|
||||
// Program notification
|
||||
Preferences::useProgramNotification(cb_program_notifications->isChecked());
|
||||
// Tracker
|
||||
Preferences::setTrackerEnabled(cb_tracker_status->isChecked());
|
||||
Preferences::setTrackerPort(spin_tracker_port->value());
|
||||
}
|
||||
|
||||
protected slots:
|
||||
@@ -195,25 +190,11 @@ 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")));
|
||||
setItem(PROGRAM_NOTIFICATIONS, PROPERTY, new QTableWidgetItem(tr("Display program notification baloons")));
|
||||
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() {
|
||||
|
||||
2692
src/bittorrent.cpp
Normal file
2692
src/bittorrent.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -46,10 +46,7 @@
|
||||
#include <libtorrent/version.hpp>
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/ip_filter.hpp>
|
||||
|
||||
#include "qtracker.h"
|
||||
#include "qtorrenthandle.h"
|
||||
#include "trackerinfos.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
@@ -62,13 +59,42 @@ class HttpServer;
|
||||
class BandwidthScheduler;
|
||||
class ScanFoldersModel;
|
||||
|
||||
class QBtSession : public QObject {
|
||||
class TrackerInfos {
|
||||
public:
|
||||
QString name_or_url;
|
||||
QString last_message;
|
||||
unsigned long num_peers;
|
||||
#if LIBTORRENT_VERSION_MINOR < 15
|
||||
bool verified;
|
||||
uint fail_count;
|
||||
#endif
|
||||
|
||||
//TrackerInfos() {}
|
||||
TrackerInfos(const TrackerInfos &b) {
|
||||
name_or_url = b.name_or_url;
|
||||
Q_ASSERT(!name_or_url.isEmpty());
|
||||
last_message = b.last_message;
|
||||
num_peers = b.num_peers;
|
||||
#if LIBTORRENT_VERSION_MINOR < 15
|
||||
verified = b.verified;
|
||||
fail_count = b.fail_count;
|
||||
#endif
|
||||
}
|
||||
TrackerInfos(QString name_or_url): name_or_url(name_or_url), last_message(""), num_peers(0) {
|
||||
#if LIBTORRENT_VERSION_MINOR < 15
|
||||
fail_count = 0;
|
||||
verified = false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
class Bittorrent : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Constructor / Destructor
|
||||
QBtSession();
|
||||
~QBtSession();
|
||||
Bittorrent();
|
||||
~Bittorrent();
|
||||
QTorrentHandle getTorrentHandle(QString hash) const;
|
||||
std::vector<torrent_handle> getTorrents() const;
|
||||
bool isFilePreviewPossible(QString fileHash) const;
|
||||
@@ -166,10 +192,6 @@ public slots:
|
||||
protected:
|
||||
QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString::null, QString root_folder=QString::null);
|
||||
bool initWebUi(QString username, QString password, int port);
|
||||
bool loadFastResumeData(QString hash, std::vector<char> &buf);
|
||||
void loadTorrentSettings(QTorrentHandle h);
|
||||
void loadTorrentTempData(QTorrentHandle h, QString savePath, bool magnet);
|
||||
add_torrent_params initializeAddTorrentParams(QString hash);
|
||||
|
||||
protected slots:
|
||||
void addTorrentsFromScanFolder(QStringList&);
|
||||
@@ -181,8 +203,6 @@ protected slots:
|
||||
void sendNotificationEmail(QTorrentHandle h);
|
||||
void autoRunExternalProgram(QTorrentHandle h, bool async=true);
|
||||
void cleanUpAutoRunProcess(int);
|
||||
void mergeTorrents(QTorrentHandle h_ex, boost::intrusive_ptr<torrent_info> t);
|
||||
void exportTorrentFile(QTorrentHandle h);
|
||||
|
||||
signals:
|
||||
void addedTorrent(QTorrentHandle& h);
|
||||
@@ -257,8 +277,6 @@ private:
|
||||
bool geoipDBLoaded;
|
||||
bool resolve_countries;
|
||||
#endif
|
||||
// Tracker
|
||||
QPointer<QTracker> m_tracker;
|
||||
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
#include "qbtsession.h"
|
||||
#include "bittorrent.h"
|
||||
#include "ui_console.h"
|
||||
|
||||
using namespace libtorrent;
|
||||
@@ -40,10 +40,10 @@ class consoleDlg : public QDialog, private Ui_ConsoleDlg{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QBtSession *BTSession;
|
||||
Bittorrent *BTSession;
|
||||
|
||||
public:
|
||||
consoleDlg(QWidget *parent, QBtSession* _BTSession) : QDialog(parent) {
|
||||
consoleDlg(QWidget *parent, Bittorrent* _BTSession) : QDialog(parent) {
|
||||
setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setModal(true);
|
||||
|
||||
@@ -73,8 +73,12 @@ void CookiesDlg::on_del_btn_clicked() {
|
||||
QList<QByteArray> CookiesDlg::getCookies() const {
|
||||
QList<QByteArray> ret;
|
||||
for(int i=0; i<ui->cookiesTable->rowCount(); ++i) {
|
||||
QString key = ui->cookiesTable->item(i, COOKIE_KEY)->text().trimmed();
|
||||
QString value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed();
|
||||
QString key;
|
||||
if(ui->cookiesTable->item(i, COOKIE_KEY))
|
||||
key = ui->cookiesTable->item(i, COOKIE_KEY)->text().trimmed();
|
||||
QString value;
|
||||
if(ui->cookiesTable->item(i, COOKIE_VALUE))
|
||||
value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed();
|
||||
if(!key.isEmpty() && !value.isEmpty()) {
|
||||
const QString raw_cookie = key+"="+value;
|
||||
qDebug("Cookie: %s", qPrintable(raw_cookie));
|
||||
|
||||
@@ -51,7 +51,7 @@ downloadThread::downloadThread(QObject* parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
void downloadThread::processDlFinished(QNetworkReply* reply) {
|
||||
QString url = reply->url().toEncoded().data();
|
||||
QString url = reply->url().toString();
|
||||
qDebug("Download finished: %s", qPrintable(url));
|
||||
if(reply->error() != QNetworkReply::NoError) {
|
||||
// Failure
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <QTemporaryFile>
|
||||
|
||||
enum EngineColumns {ENGINE_NAME, ENGINE_URL, ENGINE_STATE, ENGINE_ID};
|
||||
#define UPDATE_URL "http://qbittorrent.svn.sourceforge.net/viewvc/qbittorrent/trunk/src/search_engine/engines/"
|
||||
#define UPDATE_URL "http://qbittorrent.svn.sourceforge.net/viewvc/qbittorrent/branches/v2_4_x/src/search_engine/engines/"
|
||||
|
||||
engineSelectDlg::engineSelectDlg(QWidget *parent, SupportedEngines *supported_engines) : QDialog(parent), supported_engines(supported_engines) {
|
||||
setupUi(this);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <libtorrent/version.hpp>
|
||||
#include "eventmanager.h"
|
||||
#include "qbtsession.h"
|
||||
#include "bittorrent.h"
|
||||
#include "scannedfoldersmodel.h"
|
||||
#include "misc.h"
|
||||
#include "preferences.h"
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <QDebug>
|
||||
#include <QTranslator>
|
||||
|
||||
EventManager::EventManager(QObject *parent, QBtSession *BTSession)
|
||||
EventManager::EventManager(QObject *parent, Bittorrent *BTSession)
|
||||
: QObject(parent), BTSession(BTSession)
|
||||
{
|
||||
}
|
||||
@@ -36,20 +36,20 @@
|
||||
#include <QHash>
|
||||
#include <QVariant>
|
||||
|
||||
class QBtSession;
|
||||
class Bittorrent;
|
||||
|
||||
class EventManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QHash<QString, QVariantMap> event_list;
|
||||
QBtSession* BTSession;
|
||||
Bittorrent* BTSession;
|
||||
|
||||
protected:
|
||||
void update(QVariantMap event);
|
||||
|
||||
public:
|
||||
EventManager(QObject *parent, QBtSession* BTSession);
|
||||
EventManager(QObject *parent, Bittorrent* BTSession);
|
||||
QList<QVariantMap> getEventList() const;
|
||||
QVariantMap getPropGeneralInfo(QString hash) const;
|
||||
QList<QVariantMap> getPropTrackersInfo(QString hash) const;
|
||||
221
src/feedList.h
Normal file
221
src/feedList.h
Normal file
@@ -0,0 +1,221 @@
|
||||
#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
|
||||
514
src/feeddownloader.h
Normal file
514
src/feeddownloader.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,12 @@
|
||||
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QDir>
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
#include <QTimer>
|
||||
#include <QPointer>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
#include <QHash>
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
#include <QSet>
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
@@ -19,6 +20,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
#ifndef CIFS_MAGIC_NUMBER
|
||||
#define CIFS_MAGIC_NUMBER 0xFF534D42
|
||||
#endif
|
||||
@@ -27,6 +30,9 @@
|
||||
#define NFS_SUPER_MAGIC 0x6969
|
||||
#endif
|
||||
|
||||
const int WATCH_INTERVAL = 10000; // 10 sec
|
||||
const int MAX_PARTIAL_RETRIES = 5;
|
||||
|
||||
/*
|
||||
* Subclassing QFileSystemWatcher in order to support Network File
|
||||
* System watching (NFS, CIFS) on Linux and Mac OS.
|
||||
@@ -39,11 +45,14 @@ private:
|
||||
QList<QDir> watched_folders;
|
||||
QPointer<QTimer> watch_timer;
|
||||
#endif
|
||||
QStringList filters;
|
||||
QStringList m_filters;
|
||||
// Partial torrents
|
||||
QHash<QString, int> m_partialTorrents;
|
||||
QPointer<QTimer> m_partialTorrentTimer;
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
protected:
|
||||
bool isNetworkFileSystem(QString path) {
|
||||
private:
|
||||
static bool isNetworkFileSystem(QString path) {
|
||||
QString file = path;
|
||||
if(!file.endsWith(QDir::separator()))
|
||||
file += QDir::separator();
|
||||
@@ -99,7 +108,7 @@ protected:
|
||||
|
||||
public:
|
||||
FileSystemWatcher(QObject *parent): QFileSystemWatcher(parent) {
|
||||
filters << "*.torrent";
|
||||
m_filters << "*.torrent";
|
||||
connect(this, SIGNAL(directoryChanged(QString)), this, SLOT(scanLocalFolder(QString)));
|
||||
}
|
||||
|
||||
@@ -108,6 +117,8 @@ public:
|
||||
if(watch_timer)
|
||||
delete watch_timer;
|
||||
#endif
|
||||
if(m_partialTorrentTimer)
|
||||
delete m_partialTorrentTimer;
|
||||
}
|
||||
|
||||
QStringList directories() const {
|
||||
@@ -137,7 +148,7 @@ public:
|
||||
if (!watch_timer) {
|
||||
watch_timer = new QTimer(this);
|
||||
connect(watch_timer, SIGNAL(timeout()), this, SLOT(scanNetworkFolders()));
|
||||
watch_timer->start(5000); // 5 sec
|
||||
watch_timer->start(WATCH_INTERVAL); // 5 sec
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
@@ -196,21 +207,74 @@ protected slots:
|
||||
#endif
|
||||
}
|
||||
|
||||
void processPartialTorrents() {
|
||||
QStringList no_longer_partial;
|
||||
|
||||
// Check which torrents are still partial
|
||||
foreach(const QString& torrent_path, m_partialTorrents.keys()) {
|
||||
if(!QFile::exists(torrent_path)) {
|
||||
m_partialTorrents.remove(torrent_path);
|
||||
continue;
|
||||
}
|
||||
if(misc::isValidTorrentFile(torrent_path)) {
|
||||
no_longer_partial << torrent_path;
|
||||
m_partialTorrents.remove(torrent_path);
|
||||
} else {
|
||||
if(m_partialTorrents[torrent_path] >= MAX_PARTIAL_RETRIES) {
|
||||
m_partialTorrents.remove(torrent_path);
|
||||
QFile::rename(torrent_path, torrent_path+".invalid");
|
||||
} else {
|
||||
m_partialTorrents[torrent_path]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the partial timer if necessary
|
||||
if(m_partialTorrents.empty()) {
|
||||
m_partialTorrentTimer->stop();
|
||||
m_partialTorrentTimer->deleteLater();
|
||||
qDebug("No longer any partial torrent.");
|
||||
} else {
|
||||
qDebug("Still %d partial torrents after delayed processing.", m_partialTorrents.count());
|
||||
m_partialTorrentTimer->start(WATCH_INTERVAL);
|
||||
}
|
||||
// Notify of new torrents
|
||||
if(!no_longer_partial.isEmpty())
|
||||
emit torrentsAdded(no_longer_partial);
|
||||
}
|
||||
|
||||
signals:
|
||||
void torrentsAdded(QStringList &pathList);
|
||||
|
||||
private:
|
||||
void addTorrentsFromDir(const QDir &dir, QStringList &torrents) {
|
||||
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
|
||||
void startPartialTorrentTimer() {
|
||||
Q_ASSERT(!m_partialTorrents.isEmpty());
|
||||
if(!m_partialTorrentTimer) {
|
||||
m_partialTorrentTimer = new QTimer();
|
||||
connect(m_partialTorrentTimer, SIGNAL(timeout()), SLOT(processPartialTorrents()));
|
||||
m_partialTorrentTimer->setSingleShot(true);
|
||||
m_partialTorrentTimer->start(WATCH_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
void addTorrentsFromDir(const QDir &dir, QStringList &torrents) {
|
||||
const QStringList files = dir.entryList(m_filters, QDir::Files, QDir::Unsorted);
|
||||
foreach(const QString &file, files) {
|
||||
const QString file_abspath = dir.absoluteFilePath(file);
|
||||
if(misc::isValidTorrentFile(file_abspath)) {
|
||||
torrents << file_abspath;
|
||||
} else {
|
||||
if(!m_partialTorrents.contains(file_abspath)) {
|
||||
qDebug("Partial torrent detected at: %s", qPrintable(file_abspath));
|
||||
qDebug("Delay the file's processing...");
|
||||
m_partialTorrents.insert(file_abspath, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!m_partialTorrents.empty())
|
||||
startPartialTorrentTimer();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // FILESYSTEMWATCHER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@
|
||||
#include <QObject>
|
||||
#include <QCoreApplication>
|
||||
#include "preferences.h"
|
||||
#include "qbtsession.h"
|
||||
#include "bittorrent.h"
|
||||
|
||||
class HeadlessLoader: public QObject {
|
||||
Q_OBJECT
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
// Enable Web UI
|
||||
Preferences::setWebUiEnabled(true);
|
||||
// Instanciate Bittorrent Object
|
||||
BTSession = new QBtSession();
|
||||
BTSession = new Bittorrent();
|
||||
connect(BTSession, SIGNAL(newConsoleMessage(QString)), this, SLOT(displayConsoleMessage(QString)));
|
||||
// Resume unfinished torrents
|
||||
BTSession->startUpTorrents();
|
||||
@@ -103,7 +103,7 @@ public slots:
|
||||
}
|
||||
|
||||
private:
|
||||
QBtSession *BTSession;
|
||||
Bittorrent *BTSession;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "eventmanager.h"
|
||||
#include "preferences.h"
|
||||
#include "json.h"
|
||||
#include "qbtsession.h"
|
||||
#include "bittorrent.h"
|
||||
#include "misc.h"
|
||||
#include <QTcpSocket>
|
||||
#include <QDateTime>
|
||||
@@ -46,7 +46,7 @@
|
||||
#include <QRegExp>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
HttpConnection::HttpConnection(QTcpSocket *socket, QBtSession *BTSession, HttpServer *parent)
|
||||
HttpConnection::HttpConnection(QTcpSocket *socket, Bittorrent *BTSession, HttpServer *parent)
|
||||
: QObject(parent), socket(socket), parent(parent), BTSession(BTSession)
|
||||
{
|
||||
socket->setParent(this);
|
||||
@@ -231,13 +231,10 @@ void HttpConnection::respond() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (list[0] == "images") {
|
||||
if (list[0] == "images")
|
||||
list[0] = "Icons";
|
||||
} else {
|
||||
if(list.last().endsWith(".html"))
|
||||
list.prepend("html");
|
||||
else
|
||||
list.prepend("webui");
|
||||
}
|
||||
url = ":/" + list.join("/");
|
||||
QFile file(url);
|
||||
if(!file.open(QIODevice::ReadOnly))
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
class QTcpSocket;
|
||||
class HttpServer;
|
||||
class QBtSession;
|
||||
class Bittorrent;
|
||||
|
||||
class HttpConnection : public QObject
|
||||
{
|
||||
@@ -46,7 +46,7 @@ class HttpConnection : public QObject
|
||||
private:
|
||||
QTcpSocket *socket;
|
||||
HttpServer *parent;
|
||||
QBtSession *BTSession;
|
||||
Bittorrent *BTSession;
|
||||
|
||||
protected:
|
||||
HttpRequestParser parser;
|
||||
@@ -54,7 +54,7 @@ class HttpConnection : public QObject
|
||||
|
||||
protected slots:
|
||||
void write();
|
||||
virtual void respond();
|
||||
void respond();
|
||||
void respondJson();
|
||||
void respondGenPropertiesJson(QString hash);
|
||||
void respondTrackersPropertiesJson(QString hash);
|
||||
@@ -69,7 +69,7 @@ class HttpConnection : public QObject
|
||||
void recheckAllTorrents();
|
||||
|
||||
public:
|
||||
HttpConnection(QTcpSocket *socket, QBtSession* BTSession, HttpServer *parent);
|
||||
HttpConnection(QTcpSocket *socket, Bittorrent* BTSession, HttpServer *parent);
|
||||
~HttpConnection();
|
||||
QString translateDocument(QString data);
|
||||
|
||||
@@ -68,12 +68,12 @@ QByteArray HttpRequestParser::message() const
|
||||
|
||||
QString HttpRequestParser::get(const QString key) const
|
||||
{
|
||||
return getMap.value(key);
|
||||
return getMap[key];
|
||||
}
|
||||
|
||||
QString HttpRequestParser::post(const QString key) const
|
||||
{
|
||||
return postMap.value(key);
|
||||
return postMap[key];
|
||||
}
|
||||
|
||||
QByteArray HttpRequestParser::torrent() const
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user