1
mirror of https://github.com/qbittorrent/qBittorrent synced 2025-10-12 03:12:18 +02:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Christophe Dumez
a40b754d63 Tagged v2.4.0 release 2010-08-24 18:30:28 +00:00
Christophe Dumez
f54bc8bea4 Branched v2.4.x 2010-08-24 18:27:18 +00:00
181 changed files with 109811 additions and 14516 deletions

View File

@@ -1,9 +1,3 @@
* 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
* 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

View File

@@ -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

26
configure vendored
View File

@@ -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"
@@ -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

View File

@@ -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);
}
};

View File

@@ -1,26 +0,0 @@
/*
-----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;
}
};

View File

@@ -42,7 +42,6 @@
#include <QClipboard>
#include <QCloseEvent>
#include <QShortcut>
#include <QScrollBar>
#include "GUI.h"
#include "transferlistwidget.h"
@@ -52,7 +51,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"
@@ -72,7 +71,6 @@
void qt_mac_set_dock_menu(QMenu *menu);
#endif
#include "lineedit.h"
#include "sessionapplication.h"
using namespace libtorrent;
@@ -90,8 +88,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
ui_locked = Preferences::isUILocked();
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
displaySpeedInTitle = Preferences::speedInTitleBar();
// Clean exit on log out
connect(static_cast<SessionApplication*>(qApp), SIGNAL(sessionIsShuttingDown()), this, SLOT(deleteBTSession()));
// Setting icons
this->setWindowIcon(QIcon(QString::fromUtf8(":/Icons/skin/qbittorrent32.png")));
actionOpen->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/open.png")));
@@ -114,7 +110,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
actionSet_global_download_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/download.png")));
actionDocumentation->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/qb_question.png")));
actionLock_qBittorrent->setIcon(QIcon(QString::fromUtf8(":/Icons/oxygen/encrypted32.png")));
lockMenu = new QMenu();
QMenu *lockMenu = new QMenu();
QAction *defineUiLockPasswdAct = lockMenu->addAction(tr("Set the password..."));
connect(defineUiLockPasswdAct, SIGNAL(triggered()), this, SLOT(defineUILockPassword()));
actionLock_qBittorrent->setMenu(lockMenu);
@@ -126,7 +122,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 +198,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();
@@ -253,16 +248,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
#endif
}
void GUI::deleteBTSession() {
guiUpdater->stop();
status_bar->stopTimer();
if(BTSession) {
delete BTSession;
BTSession = 0;
}
QTimer::singleShot(0, this, SLOT(close()));
}
// Destructor
GUI::~GUI() {
qDebug("GUI destruction");
@@ -273,9 +258,7 @@ GUI::~GUI() {
#endif
// Async deletion of Bittorrent session as early as possible
// in order to speed up exit
session_proxy sp;
if(BTSession)
sp = BTSession->asyncDeletion();
session_proxy sp = BTSession->asyncDeletion();
// Some saving
properties->saveSettings();
disconnect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int)));
@@ -286,7 +269,6 @@ GUI::~GUI() {
delete search_filter;
delete transferList;
delete guiUpdater;
delete lockMenu;
if(createTorrentDlg)
delete createTorrentDlg;
if(console)
@@ -542,7 +524,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() {
@@ -680,7 +662,7 @@ void GUI::closeEvent(QCloseEvent *e) {
e->accept();
return;
}
if(settings.value(QString::fromUtf8("Preferences/General/ExitConfirm"), true).toBool() && BTSession && BTSession->hasActiveTorrents()) {
if(settings.value(QString::fromUtf8("Preferences/General/ExitConfirm"), true).toBool() && BTSession->hasActiveTorrents()) {
if(e->spontaneous() || force_exit) {
if(!isVisible())
show();
@@ -922,6 +904,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 +929,7 @@ void GUI::loadPreferences(bool configure_session) {
delete myTrayIconMenu;
}
}
#endif
// General
if(Preferences::isToolbarDisplayed()) {
toolBar->setVisible(true);
@@ -1009,8 +993,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 +1013,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)));
}
@@ -1047,8 +1033,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 +1073,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 +1094,7 @@ void GUI::createSystrayDelayed() {
Preferences::setSystrayIntegration(false);
}
}
#endif
}
void GUI::updateAltSpeedsBtn(bool alternative) {
@@ -1171,11 +1161,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);

View File

@@ -37,7 +37,7 @@
#include "ui_mainwindow.h"
#include "qtorrenthandle.h"
class QBtSession;
class Bittorrent;
class QTimer;
class downloadFromURL;
class SearchEngine;
@@ -80,7 +80,6 @@ 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
@@ -140,7 +139,7 @@ protected:
private:
QFileSystemWatcher *executable_watcher;
// Bittorrent
QBtSession *BTSession;
Bittorrent *BTSession;
QList<QPair<QTorrentHandle,QString> > unauthenticated_trackers; // Still needed?
// GUI related
QTimer *guiUpdater;
@@ -171,7 +170,6 @@ private:
QAction *prioSeparator2;
QSplitter *hSplitter;
QSplitter *vSplitter;
QMenu *lockMenu;
// Search
QPointer<SearchEngine> searchEngine;
// RSS
@@ -183,7 +181,6 @@ 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();
};
#endif

View File

@@ -1,6 +1,6 @@
[Desktop Entry]
Categories=Qt;Network;P2P;
Comment=V2.5.0
Comment=V2.4.0
Exec=qbittorrent %f
GenericName=Bittorrent client
GenericName[ar]=العميل Bittorrent

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -47,7 +47,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>2.5.0</string>
<string>2.4.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>

View File

@@ -1,6 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>gpl.html</file>
</qresource>
</RCC>

File diff suppressed because it is too large Load Diff

View File

@@ -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() {

2656
src/bittorrent.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -191,8 +191,7 @@ void createtorrent::on_createButton_clicked(){
QString destination = QFileDialog::getSaveFileName(this, tr("Select destination torrent file"), last_path, tr("Torrent Files")+QString::fromUtf8(" (*.torrent)"));
if(!destination.isEmpty()) {
settings.setValue("CreateTorrent/last_save_path", misc::removeLastPathPart(destination));
if(!destination.toUpper().endsWith(".TORRENT"))
destination += QString::fromUtf8(".torrent");
destination += QString::fromUtf8(".torrent");
} else {
return;
}
@@ -220,22 +219,16 @@ void createtorrent::handleCreationSuccess(QString path, QString branch_path) {
// Remove busy cursor
setCursor(QCursor(Qt::ArrowCursor));
if(checkStartSeeding->isChecked()) {
QString root_folder;
// Create save path temp data
boost::intrusive_ptr<torrent_info> t;
try {
t = new torrent_info(path.toUtf8().data());
root_folder = misc::truncateRootFolder(t);
} catch(std::exception&) {
QMessageBox::critical(0, tr("Torrent creation"), tr("Created torrent file is invalid. It won't be added to download list."));
return;
}
QString hash = misc::toQString(t->info_hash());
QString save_path = branch_path;
if(!root_folder.isEmpty()) {
save_path = QDir(save_path).absoluteFilePath(root_folder);
}
TorrentTempData::setSavePath(hash, save_path);
TorrentTempData::setSavePath(hash, branch_path);
#if LIBTORRENT_VERSION_MINOR > 14
// Enable seeding mode (do not recheck the files)
TorrentTempData::setSeedingMode(hash, true);
@@ -291,7 +284,8 @@ void torrentCreatorThread::run() {
char const* creator_str = "qBittorrent "VERSION;
try {
file_storage fs;
path full_path = complete(path(input_path.toUtf8().constData()));
file_pool fp;
path full_path = complete(path(input_path.toLocal8Bit().data()));
// Adding files to the torrent
add_files(fs, full_path, file_filter);
if(abort) return;
@@ -316,7 +310,7 @@ void torrentCreatorThread::run() {
t.set_priv(is_private);
if(abort) return;
// create the torrent and print it to out
ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary);
ofstream out(complete(path((const char*)save_path.toLocal8Bit())), std::ios_base::binary);
bencode(std::ostream_iterator<char>(out), t.generate());
emit updateProgress(100);
emit creationSuccess(save_path, QString::fromUtf8(full_path.branch_path().string().c_str()));

View File

@@ -60,34 +60,31 @@ public:
pix.fill();
pixmap = pix;
} else {
const qulonglong nb_pieces = pieces.size();
const int nb_pieces = pieces.size();
// Reduce the number of pieces before creating the pixmap
// otherwise it can crash when there are too many pieces
const uint w = width();
if(nb_pieces > w) {
const uint ratio = floor(nb_pieces/(double)w);
bitfield scaled_pieces(ceil(nb_pieces/(double)ratio), false);
bitfield scaled_downloading(ceil(nb_pieces/(double)ratio), false);
uint scaled_index = 0;
for(qulonglong i=0; i<nb_pieces; i+= ratio) {
if(nb_pieces > width()) {
const int ratio = floor(nb_pieces/(double)width());
std::vector<bool> scaled_pieces;
std::vector<bool> scaled_downloading;
for(int i=0; i<nb_pieces; i+= ratio) {
bool have = true;
for(qulonglong j=i; j<qMin(i+ratio, nb_pieces); ++j) {
for(int j=i; j<qMin(i+ratio, nb_pieces); ++j) {
if(!pieces[i]) { have = false; break; }
}
scaled_pieces.push_back(have);
if(have) {
scaled_pieces.set_bit(scaled_index);
scaled_downloading.push_back(false);
} else {
bool downloading = false;
for(qulonglong j=i; j<qMin(i+ratio, nb_pieces); ++j) {
for(int j=i; j<qMin(i+ratio, nb_pieces); ++j) {
if(downloading_pieces[i]) { downloading = true; break; }
}
if(downloading)
scaled_downloading.set_bit(scaled_index);
scaled_downloading.push_back(downloading);
}
++scaled_index;
}
QPixmap pix = QPixmap(scaled_pieces.size(), 1);
//pix.fill();
pix.fill();
QPainter painter(&pix);
for(uint i=0; i<scaled_pieces.size(); ++i) {
if(scaled_pieces[i]) {
@@ -104,7 +101,7 @@ public:
pixmap = pix;
} else {
QPixmap pix = QPixmap(pieces.size(), 1);
//pix.fill();
pix.fill();
QPainter painter(&pix);
for(uint i=0; i<pieces.size(); ++i) {
if(pieces[i]) {

View File

@@ -270,7 +270,6 @@ void engineSelectDlg::installPlugin(QString path, QString plugin_name) {
// Backup in case install fails
QFile::copy(dest_path, dest_path+".bak");
misc::safeRemove(dest_path);
misc::safeRemove(dest_path+"c");
update = true;
}
// Copy the plugin

View File

@@ -31,16 +31,15 @@
#include <libtorrent/version.hpp>
#include "eventmanager.h"
#include "qbtsession.h"
#include "bittorrent.h"
#include "scannedfoldersmodel.h"
#include "misc.h"
#include "preferences.h"
//#include "proplistdelegate.h"
#include "torrentpersistentdata.h"
#include <QDebug>
#include <QTranslator>
EventManager::EventManager(QObject *parent, QBtSession *BTSession)
EventManager::EventManager(QObject *parent, Bittorrent *BTSession)
: QObject(parent), BTSession(BTSession)
{
}
@@ -125,20 +124,8 @@ QList<QVariantMap> EventManager::getPropFilesInfo(QString hash) const {
void EventManager::setGlobalPreferences(QVariantMap m) const {
// UI
if(m.contains("locale")) {
QString locale = m["locale"].toString();
if(Preferences::getLocale() != locale) {
QTranslator *translator = new QTranslator;
if(translator->load(QString::fromUtf8(":/lang/qbittorrent_") + locale)){
qDebug("%s locale recognized, using translation.", qPrintable(locale));
}else{
qDebug("%s locale unrecognized, using default (en_GB).", qPrintable(locale));
}
qApp->installTranslator(translator);
}
Preferences::setLocale(locale);
}
if(m.contains("locale"))
Preferences::setLocale(m["locale"].toString());
// Downloads
if(m.contains("save_path"))
Preferences::setSavePath(m["save_path"].toString());

View File

@@ -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
View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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;
};

View File

@@ -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,8 +46,8 @@
#include <QRegExp>
#include <QTemporaryFile>
HttpConnection::HttpConnection(QTcpSocket *socket, QBtSession *BTSession, HttpServer *parent)
: QObject(parent), socket(socket), parent(parent), BTSession(BTSession)
HttpConnection::HttpConnection(QTcpSocket *socket, Bittorrent *BTSession, HttpServer *parent)
: QObject(parent), socket(socket), parent(parent), BTSession(BTSession)
{
socket->setParent(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(read()));
@@ -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))

View File

@@ -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;
@@ -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);

View File

@@ -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