1
mirror of https://github.com/qbittorrent/qBittorrent synced 2025-10-21 13:52:16 +02:00

Compare commits

..

39 Commits

Author SHA1 Message Date
Christophe Dumez
1e013a053e Tagged v2.4.0rc1 release 2010-08-20 13:26:45 +00:00
Christophe Dumez
92fc212a0e FEATURE: Run external program on torrent completion 2010-08-20 13:20:23 +00:00
Christophe Dumez
6f4d7b7c1b Clean up 2010-08-20 12:35:13 +00:00
Christophe Dumez
63ee1c36e8 FEATURE: Added torrent filtering by name 2010-08-20 12:27:20 +00:00
Christophe Dumez
7d07debcb5 Cleaner program exit on Auto-shutdown 2010-08-20 09:35:28 +00:00
Christophe Dumez
dd67e1ee9d Code cleanup 2010-08-20 09:33:44 +00:00
Christophe Dumez
493efdbf10 Bump to beta3 2010-08-20 09:31:24 +00:00
Christophe Dumez
e323175275 Fix possible crash when using the new "Auto-shutdown" feature 2010-08-20 09:31:00 +00:00
Christophe Dumez
c1fa7f8645 Code cleanup 2010-08-20 09:02:27 +00:00
Christophe Dumez
275b962363 Added missing include 2010-08-19 20:23:39 +00:00
Christophe Dumez
3847c33017 Updated French translation 2010-08-19 19:37:29 +00:00
Christophe Dumez
9e21f52213 Updated language files 2010-08-19 19:16:44 +00:00
Christophe Dumez
25cf9b33ec Bump to beta2 2010-08-19 19:12:25 +00:00
Christophe Dumez
c7a2d3589f Updated Web UI to reflect the mail notification changes 2010-08-19 19:10:46 +00:00
Christophe Dumez
d8dd3834c3 Email notification on download completion 2010-08-19 18:47:57 +00:00
Christophe Dumez
ee01c2c745 FEATURE: Added button to password-lock the UI 2010-08-19 16:30:13 +00:00
Christophe Dumez
e7e5a2b4e9 Fix "Set location" action 2010-08-18 08:46:04 +00:00
Christophe Dumez
ff16f59be1 Fix per-label pause/resume actions 2010-08-18 08:07:17 +00:00
Christophe Dumez
2cd4937ddc Mac specific changes by Stephanos Antaris 2010-08-17 10:50:14 +00:00
Christophe Dumez
0e9abc1762 Bump to v2.4.0beta1 2010-08-17 08:51:12 +00:00
Christophe Dumez
e24ce87946 FEATURE: Added label-level Pause/Resume/Delete actions 2010-08-17 08:42:30 +00:00
Christophe Dumez
308e358d3f Fix Auto-Shutdown feature on Windows 2010-08-16 18:34:30 +00:00
Christophe Dumez
d15e6a4847 Blind implementation for auto-shutdown on Windows 2010-08-16 17:57:15 +00:00
Christophe Dumez
e311239a28 Blind implementation of auto-shutdown for Mac OS 2010-08-16 17:42:21 +00:00
Christophe Dumez
df677789d2 FEATURE: Added Auto-Shutdown on downloads completion feature (Linux Only for now) 2010-08-16 17:35:32 +00:00
Christophe Dumez
0af44eadb6 Fix possible folder watching issues on Windows 2010-08-16 11:51:50 +00:00
Christophe Dumez
85cafe530e Fix to last commit 2010-08-16 09:20:49 +00:00
Christophe Dumez
7609db28f1 Fix scan folder display on Windows and OS/2 2010-08-16 08:58:25 +00:00
Christophe Dumez
fefda39284 Added priority actions to Web UI right-click menu 2010-08-15 08:49:19 +00:00
Christophe Dumez
b2f98bd059 Priority actions should work only if the tab is displayed 2010-08-15 07:47:33 +00:00
Christophe Dumez
26c69fe6d4 Priority actions are only effective if the transfer list tab is displayed 2010-08-15 07:45:20 +00:00
Christophe Dumez
bf4f1a7c37 Fix speed limit sliders initialization in Web UI 2010-08-15 07:39:36 +00:00
Christophe Dumez
9b0dd39d9d Added missing icon 2010-08-15 07:23:37 +00:00
Christophe Dumez
66d4cc2ab8 FEATURE: Added actions to "Move to top/bottom" of priority queue 2010-08-14 15:53:05 +00:00
Christophe Dumez
0bcbaf6521 Remember last selected paths in torrent creation dialog 2010-08-13 14:02:19 +00:00
Christophe Dumez
e074872b24 Fix about dialog layout 2010-08-13 13:35:24 +00:00
Christophe Dumez
63ec1e618e Fix compilation with gcc 4.5 2010-08-13 13:29:17 +00:00
Christophe Dumez
331c15b76c Bump to v2.4.0alpha 2010-07-27 08:07:46 +00:00
Christophe Dumez
d2089c9aad Updated about dialog 2010-07-27 00:00:52 +00:00
114 changed files with 11925 additions and 5815 deletions

View File

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

View File

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

View File

@@ -69,6 +69,7 @@
#include "qmacapplication.h"
void qt_mac_set_dock_menu(QMenu *menu);
#endif
#include "lineedit.h"
using namespace libtorrent;
@@ -83,7 +84,7 @@ using namespace libtorrent;
// Constructor
GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), force_exit(false) {
setupUi(this);
ui_locked = Preferences::isUILocked();
setWindowTitle(tr("qBittorrent %1", "e.g: qBittorrent v0.x").arg(QString::fromUtf8(VERSION)));
displaySpeedInTitle = Preferences::speedInTitleBar();
// Setting icons
@@ -107,6 +108,11 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
actionSet_global_upload_limit->setIcon(QIcon(QString::fromUtf8(":/Icons/skin/seeding.png")));
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")));
QMenu *lockMenu = new QMenu();
QAction *defineUiLockPasswdAct = lockMenu->addAction(tr("Set the password..."));
connect(defineUiLockPasswdAct, SIGNAL(triggered()), this, SLOT(defineUILockPassword()));
actionLock_qBittorrent->setMenu(lockMenu);
prioSeparator = toolBar->insertSeparator(actionDecreasePriority);
prioSeparator2 = menu_Edit->insertSeparator(actionDecreasePriority);
prioSeparator->setVisible(false);
@@ -149,6 +155,12 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
connect(transferList, SIGNAL(torrentStatusUpdate(uint,uint,uint,uint,uint)), this, SLOT(updateNbTorrents(uint,uint,uint,uint,uint)));
vboxLayout->addWidget(tabs);
// Name filter
search_filter = new LineEdit();
toolBar->addWidget(search_filter);
search_filter->setFixedWidth(200);
connect(search_filter, SIGNAL(textChanged(QString)), transferList, SLOT(applyNameFilter(QString)));
// Transfer list slots
connect(actionStart, SIGNAL(triggered()), transferList, SLOT(startSelectedTorrents()));
connect(actionStart_All, SIGNAL(triggered()), transferList, SLOT(startAllTorrents()));
@@ -160,10 +172,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
// Configure BT session according to options
loadPreferences(false);
// Resume unfinished torrents
BTSession->startUpTorrents();
// Add torrent given on command line
processParams(torrentCmdLine);
// Start connection checking timer
guiUpdater = new QTimer(this);
@@ -187,6 +195,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
actionSearch_engine->setChecked(Preferences::isSearchEnabled());
displaySearchTab(actionSearch_engine->isChecked());
displayRSSTab(actionRSS_Reader->isChecked());
actionShutdown_when_downloads_complete->setChecked(Preferences::shutdownWhenDownloadsComplete());
show();
@@ -203,10 +212,18 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), for
}while(transferListFilters->getStatusFilters()->verticalScrollBar()->sliderPosition() > 0);
transferListFilters->getStatusFilters()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
if(Preferences::startMinimized()) {
showMinimized();
if(ui_locked) {
hide();
} else {
if(Preferences::startMinimized())
showMinimized();
}
// Resume unfinished torrents
BTSession->startUpTorrents();
// Add torrent given on command line
processParams(torrentCmdLine);
qDebug("GUI Built");
#ifdef Q_WS_WIN
if(!Preferences::neverCheckFileAssoc() && !Preferences::isFileAssocOk()) {
@@ -240,6 +257,7 @@ GUI::~GUI() {
disconnect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tab_changed(int)));
// Delete other GUI objects
delete status_bar;
delete search_filter;
delete transferList;
delete guiUpdater;
if(createTorrentDlg)
@@ -276,10 +294,8 @@ GUI::~GUI() {
delete switchTransferShortcut;
delete switchRSSShortcut;
// Delete BTSession objects
qDebug("Deleting BTSession");
delete BTSession;
// Deleting remaining top level widgets
qDebug("Deleting remaining top level widgets");
// May freeze for a few seconds after the next line
// because the Bittorrent session proxy will
// actually be deleted now and destruction
@@ -287,6 +303,34 @@ GUI::~GUI() {
qDebug("Exiting GUI destructor...");
}
void GUI::defineUILockPassword() {
QString old_pass_md5 = Preferences::getUILockPasswordMD5();
if(old_pass_md5.isNull()) old_pass_md5 = "";
bool ok = false;
QString new_clear_password = QInputDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, old_pass_md5, &ok);
if(ok) {
if(new_clear_password != old_pass_md5) {
Preferences::setUILockPassword(new_clear_password);
}
QMessageBox::information(this, tr("Password update"), tr("The UI lock password has been successfully updated"));
}
}
void GUI::on_actionLock_qBittorrent_triggered() {
// Check if there is a password
if(Preferences::getUILockPasswordMD5().isEmpty()) {
// Ask for a password
bool ok = false;
QString clear_password = QInputDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, "", &ok);
if(!ok) return;
Preferences::setUILockPassword(clear_password);
}
// Lock the interface
ui_locked = true;
Preferences::setUILocked(true);
hide();
}
void GUI::displayRSSTab(bool enable) {
if(enable) {
// RSS tab
@@ -528,10 +572,32 @@ void GUI::setTabText(int index, QString text) const {
tabs->setTabText(index, text);
}
bool GUI::unlockUI() {
bool ok = false;
QString clear_password = QInputDialog::getText(this, tr("UI lock password"), tr("Please type the UI lock password:"), QLineEdit::Password, "", &ok);
if(!ok) return false;
QString real_pass_md5 = Preferences::getUILockPasswordMD5();
QCryptographicHash md5(QCryptographicHash::Md5);
md5.addData(clear_password.toLocal8Bit());
QString password_md5 = md5.result().toHex();
if(real_pass_md5 == password_md5) {
ui_locked = false;
Preferences::setUILocked(false);
return true;
}
QMessageBox::warning(this, tr("Invalid password"), tr("The password is invalid"));
return false;
}
// Toggle Main window visibility
void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e) {
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
if(isHidden()) {
if(ui_locked) {
// Ask for UI lock password
if(!unlockUI())
return;
}
show();
if(isMinimized()) {
if(isMaximized()) {
@@ -738,8 +804,8 @@ void GUI::on_actionOpen_triggered() {
// Open File Open Dialog
// Note: it is possible to select more than one file
const QStringList pathsList = QFileDialog::getOpenFileNames(0,
tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(),
tr("Torrent Files")+QString::fromUtf8(" (*.torrent)"));
tr("Open Torrent Files"), settings.value(QString::fromUtf8("MainWindowLastDir"), QDir::homePath()).toString(),
tr("Torrent Files")+QString::fromUtf8(" (*.torrent)"));
if(!pathsList.empty()) {
const bool useTorrentAdditionDialog = settings.value(QString::fromUtf8("Preferences/Downloads/AdditionDialog"), true).toBool();
const uint listSize = pathsList.size();
@@ -821,6 +887,7 @@ 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)) {
if(newSystrayIntegration) {
// create the trayicon
@@ -1066,6 +1133,11 @@ void GUI::on_actionTop_tool_bar_triggered() {
Preferences::setToolbarDisplayed(is_visible);
}
void GUI::on_actionShutdown_when_downloads_complete_triggered() {
bool is_checked = static_cast<QAction*>(sender())->isChecked();
Preferences::setShutdownWhenDownloadsComplete(is_checked);
}
void GUI::on_actionSpeed_in_title_bar_triggered() {
displaySpeedInTitle = static_cast<QAction*>(sender())->isChecked();
Preferences::showSpeedInTitleBar(displaySpeedInTitle);

View File

@@ -57,6 +57,7 @@ class about;
class createtorrent;
class downloadFromURL;
class HidableTabWidget;
class LineEdit;
class GUI : public QMainWindow, private Ui::MainWindow{
Q_OBJECT
@@ -69,6 +70,7 @@ public:
QWidget* getCurrentTabWidget() const;
TransferListWidget* getTransferList() const { return transferList; }
QMenu* getTrayIconMenu();
PropertiesWidget *getProperties() const { return properties; }
public slots:
void trackerAuthenticationRequired(QTorrentHandle& h);
@@ -97,6 +99,9 @@ protected slots:
void handleDownloadFromUrlFailure(QString, QString) const;
void createSystrayDelayed();
void tab_changed(int);
void on_actionLock_qBittorrent_triggered();
void defineUILockPassword();
bool unlockUI();
// Keyboard shortcuts
void createKeyboardShortcuts();
void displayTransferTab() const;
@@ -150,6 +155,8 @@ private:
PropertiesWidget *properties;
bool displaySpeedInTitle;
bool force_exit;
bool ui_locked;
LineEdit *search_filter;
// Keyboard shortcuts
QShortcut *switchSearchShortcut;
QShortcut *switchSearchShortcut2;
@@ -170,6 +177,7 @@ 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();
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

BIN
src/Icons/oxygen/go-top.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

BIN
src/Icons/oxygen/go-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

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.3.0</string>
<string>2.4.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>

View File

@@ -47,7 +47,6 @@ class about : public QDialog, private Ui::AboutDlg{
setAttribute(Qt::WA_DeleteOnClose);
// Set icons
logo->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/qbittorrent22.png")));
mascot_lbl->setPixmap(QPixmap(QString::fromUtf8(":/Icons/skin/mascot.png")));
//Title
lb_name->setText(QString::fromUtf8("<b><h1>")+tr("qBittorrent")+QString::fromUtf8(" "VERSION"</h1></b>"));
// Thanks

View File

@@ -34,8 +34,10 @@
#include <QNetworkInterface>
#include <QHostAddress>
#include <QNetworkAddressEntry>
#include <QProcess>
#include <stdlib.h>
#include "smtp.h"
#include "filesystemwatcher.h"
#include "bittorrent.h"
#include "misc.h"
@@ -203,7 +205,7 @@ bool Bittorrent::isPexEnabled() const {
void Bittorrent::processBigRatios() {
if(ratio_limit <= 0) return;
qDebug("Process big ratios...");
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
const QTorrentHandle h(*torrentIT);
@@ -366,7 +368,7 @@ void Bittorrent::configureSession() {
geoipDBLoaded = true;
}
// Update torrent handles
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -700,17 +702,13 @@ qlonglong Bittorrent::getETA(QString hash) {
return (qlonglong) floor((double) (bytes_left) / avg_speed);
}
std::vector<torrent_handle> Bittorrent::getTorrents() const {
return s->get_torrents();
}
// Return the torrent handle, given its hash
QTorrentHandle Bittorrent::getTorrentHandle(QString hash) const{
return QTorrentHandle(s->find_torrent(misc::QStringToSha1(hash)));
}
bool Bittorrent::hasActiveTorrents() const {
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
const QTorrentHandle h(*torrentIT);
@@ -720,6 +718,21 @@ bool Bittorrent::hasActiveTorrents() const {
return false;
}
bool Bittorrent::hasDownloadingTorrents() const {
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
if(torrentIT->is_valid()) {
try {
const torrent_status::state_t state = torrentIT->status().state;
if(state != torrent_status::finished && state != torrent_status::seeding)
return true;
} catch(std::exception) {}
}
}
return false;
}
void Bittorrent::banIP(QString ip) {
FilterParserThread::processFilterList(s, QStringList(ip));
Preferences::banIP(ip);
@@ -763,7 +776,7 @@ void Bittorrent::deleteTorrent(QString hash, bool delete_local_files) {
}
void Bittorrent::pauseAllTorrents() {
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -775,8 +788,12 @@ void Bittorrent::pauseAllTorrents() {
}
}
std::vector<torrent_handle> Bittorrent::getTorrents() const {
return s->get_torrents();
}
void Bittorrent::resumeAllTorrents() {
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -841,7 +858,7 @@ QTorrentHandle Bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
if (load_file(fastresume_path.toLocal8Bit().constData(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
qDebug("Successfuly loaded");
qDebug("Successfully loaded");
}
}
QString torrent_name = misc::magnetUriToName(magnet_uri);
@@ -1087,7 +1104,7 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
if (load_file(fastresume_path.toLocal8Bit().constData(), buf) == 0) {
fastResume = true;
p.resume_data = &buf;
qDebug("Successfuly loaded");
qDebug("Successfully loaded");
}
}
QString savePath;
@@ -1660,7 +1677,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(temppath.isEmpty()) {
// Disabling temp dir
// Moving all torrents to their destination folder
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -1670,7 +1687,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
} else {
qDebug("Enabling default temp path...");
// Moving all downloading torrents to temporary save path
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -1752,7 +1769,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
appendLabelToSavePath = !appendLabelToSavePath;
if(appendLabelToSavePath) {
// Move torrents storage to sub folder with label name
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -1767,7 +1784,7 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
if(appendqBExtension != append) {
appendqBExtension = !appendqBExtension;
// append or remove .!qB extension for incomplete files
std::vector<torrent_handle> torrents = getTorrents();
std::vector<torrent_handle> torrents = s->get_torrents();
std::vector<torrent_handle>::iterator torrentIT;
for(torrentIT = torrents.begin(); torrentIT != torrents.end(); torrentIT++) {
QTorrentHandle h = QTorrentHandle(*torrentIT);
@@ -1953,6 +1970,42 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
}
}
void Bittorrent::cleanUpAutoRunProcess(int) {
sender()->deleteLater();
}
void Bittorrent::autoRunExternalProgram(QTorrentHandle h, bool async) {
if(!h.is_valid()) return;
QString program = Preferences::getAutoRunProgram().trimmed();
if(program.isEmpty()) return;
// Replace %f by torrent path
QString torrent_path;
if(h.num_files() == 1)
torrent_path = h.firstFileSavePath();
else
torrent_path = h.save_path();
program.replace("%f", torrent_path);
QProcess *process = new QProcess;
if(async) {
connect(process, SIGNAL(finished(int)), this, SLOT(cleanUpAutoRunProcess(int)));
process->start(program);
} else {
process->execute(program);
delete process;
}
}
void Bittorrent::sendNotificationEmail(QTorrentHandle h) {
// Prepare mail content
QString content = tr("Torrent name: %1").arg(h.name()) + "\n";
content += tr("Torrent size: %1").arg(misc::friendlyUnit(h.actual_size())) + "\n";
content += tr("Save path: %1").arg(TorrentPersistentData::getSavePath(h.hash())) + "\n\n";
content += tr("The torrent was downloaded in %1.", "The torrent was downloaded in 1 hour and 20 seconds").arg(misc::userFriendlyDuration(h.active_time())) + "\n\n\n";
content += tr("Thank you for using qBittorrent.") + "\n";
// Send the notification email
new Smtp("notification@qbittorrent.org", Preferences::getMailNotificationEmail(), tr("[qBittorrent] %1 has finished downloading").arg(h.name()), content);
}
// Read alerts sent by the Bittorrent session
void Bittorrent::readAlerts() {
// look at session alerts and display some infos
@@ -2013,6 +2066,31 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
TorrentPersistentData::saveSeedStatus(h);
}
qDebug("Received finished alert for %s", qPrintable(h.name()));
if(!was_already_seeded) {
bool will_shutdown = Preferences::shutdownWhenDownloadsComplete() && !hasDownloadingTorrents();
// AutoRun program
if(Preferences::isAutoRunEnabled())
autoRunExternalProgram(h, will_shutdown);
// Mail notification
if(Preferences::isMailNotificationEnabled())
sendNotificationEmail(h);
// Auto-Shutdown
if(will_shutdown) {
qDebug("Preparing for auto-shutdown because all downloads are complete!");
#if LIBTORRENT_VERSION_MINOR < 15
saveDHTEntry();
#endif
qDebug("Saving session state");
saveSessionState();
qDebug("Saving fast resume data");
saveFastResumeData();
qDebug("Sending computer shutdown signal");
misc::shutdownComputer();
qDebug("Exiting the application");
qApp->exit();
return;
}
}
}
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) {

View File

@@ -108,6 +108,7 @@ public:
session* getSession() const;
QHash<QString, TrackerInfos> getTrackersInfo(QString hash) const;
bool hasActiveTorrents() const;
bool hasDownloadingTorrents() const;
bool isQueueingEnabled() const;
int getMaximumActiveDownloads() const;
int getMaximumActiveTorrents() const;
@@ -199,6 +200,9 @@ protected slots:
void takeETASamples();
void exportTorrentFiles(QString path);
void saveTempFastResumeData();
void sendNotificationEmail(QTorrentHandle h);
void autoRunExternalProgram(QTorrentHandle h, bool async=true);
void cleanUpAutoRunProcess(int);
signals:
void addedTorrent(QTorrentHandle& h);

View File

@@ -50,6 +50,7 @@
#include "torrentpersistentdata.h"
#include "createtorrent_imp.h"
#include "misc.h"
#include "qinisettings.h"
using namespace libtorrent;
using namespace boost::filesystem;
@@ -80,8 +81,11 @@ createtorrent::~createtorrent() {
}
void createtorrent::on_addFolder_button_clicked(){
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly);
QIniSettings settings("qBittorrent", "qBittorrent");
QString last_path = settings.value("CreateTorrent/last_add_path", QDir::homePath()).toString();
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), last_path, QFileDialog::ShowDirsOnly);
if(!dir.isEmpty()) {
settings.setValue("CreateTorrent/last_add_path", dir);
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
dir = dir.replace("/", "\\");
#endif
@@ -90,8 +94,11 @@ void createtorrent::on_addFolder_button_clicked(){
}
void createtorrent::on_addFile_button_clicked(){
QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath());
QIniSettings settings("qBittorrent", "qBittorrent");
QString last_path = settings.value("CreateTorrent/last_add_path", QDir::homePath()).toString();
QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), last_path);
if(!file.isEmpty()) {
settings.setValue("CreateTorrent/last_add_path", misc::removeLastPathPart(file));
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
file = file.replace("/", "\\");
#endif
@@ -177,14 +184,14 @@ void createtorrent::on_createButton_clicked(){
return;
}
QStringList trackers = allItems(trackers_list);
/*if(!trackers.size()){
QMessageBox::critical(0, tr("No tracker path set"), tr("Please set at least one tracker"));
return;
}*/
QString destination = QFileDialog::getSaveFileName(this, tr("Select destination torrent file"), QDir::homePath(), tr("Torrent Files")+QString::fromUtf8(" (*.torrent)"));
QIniSettings settings("qBittorrent", "qBittorrent");
QString last_path = settings.value("CreateTorrent/last_save_path", QDir::homePath()).toString();
QString destination = QFileDialog::getSaveFileName(this, tr("Select destination torrent file"), last_path, tr("Torrent Files")+QString::fromUtf8(" (*.torrent)"));
if(!destination.isEmpty()) {
if(!destination.endsWith(QString::fromUtf8(".torrent")))
destination += QString::fromUtf8(".torrent");
settings.setValue("CreateTorrent/last_save_path", misc::removeLastPathPart(destination));
destination += QString::fromUtf8(".torrent");
} else {
return;
}

View File

@@ -163,6 +163,12 @@ void EventManager::setGlobalPreferences(QVariantMap m) const {
}
if(m.contains("export_dir"))
Preferences::setExportDir(m["export_dir"].toString());
if(m.contains("mail_notification_enabled"))
Preferences::setMailNotificationEnabled(m["mail_notification_enabled"].toBool());
if(m.contains("mail_notification_email"))
Preferences::setMailNotificationEmail(m["mail_notification_email"].toString());
if(m.contains("mail_notification_smtp"))
Preferences::setMailNotificationSMTP(m["mail_notification_smtp"].toString());
if(m.contains("preallocate_all"))
Preferences::preAllocateAllFiles(m["preallocate_all"].toBool());
if(m.contains("queueing_enabled"))
@@ -265,6 +271,9 @@ QVariantMap EventManager::getGlobalPreferences() const {
data["download_in_scan_dirs"] = var_list;
data["export_dir_enabled"] = Preferences::isTorrentExportEnabled();
data["export_dir"] = Preferences::getExportDir();
data["mail_notification_enabled"] = Preferences::isMailNotificationEnabled();
data["mail_notification_email"] = Preferences::getMailNotificationEmail();
data["mail_notification_smtp"] = Preferences::getMailNotificationSMTP();
data["preallocate_all"] = Preferences::preAllocateAllFiles();
data["queueing_enabled"] = Preferences::isQueueingSystemEnabled();
data["max_active_downloads"] = Preferences::getMaxActiveDownloads();

View File

@@ -202,8 +202,13 @@ 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;
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
}
}
};

View File

@@ -161,7 +161,7 @@ void HttpConnection::respond() {
write();
return;
}
// Client sucessfuly authenticated, reset number of failed attempts
// Client successfully authenticated, reset number of failed attempts
parent->resetNbFailedAttemptsForIp(peer_ip);
QString url = parser.url();
// Favicon
@@ -500,6 +500,16 @@ void HttpConnection::respondCommand(QString command)
if(h.is_valid()) h.queue_position_down();
return;
}
if(command == "topPrio") {
QTorrentHandle h = BTSession->getTorrentHandle(parser.post("hash"));
if(h.is_valid()) h.queue_position_top();
return;
}
if(command == "bottomPrio") {
QTorrentHandle h = BTSession->getTorrentHandle(parser.post("hash"));
if(h.is_valid()) h.queue_position_bottom();
return;
}
if(command == "recheck"){
recheckTorrent(parser.post("hash"));
return;

File diff suppressed because it is too large Load Diff

View File

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

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

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