diff --git a/Changelog b/Changelog index 612a8cade..4ebb3faa3 100644 --- a/Changelog +++ b/Changelog @@ -10,6 +10,7 @@ - FEATURE: Search engine results can now be opened in a Web browser - FEATURE: Added a search engine plugin to extratorrent.com - FEATURE: Added a search engine plugin for kickasstorrents.com + - FEATURE: Added auto-suspend upon downloads completion feature - COSMETIC: Same deletion confirmation dialog in the GUI and Web UI - COSMETIC: Simplified the top toolbar - COSMETIC: Display execution log as a tab instead of a modal window diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7c8687f3d..f94b0607a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -124,6 +124,7 @@ MainWindow::MainWindow(QWidget *parent, QStringList torrentCmdLine) : QMainWindo actionStart->setIcon(misc::getIcon("media-playback-start")); actionStart_All->setIcon(misc::getIcon("media-playback-start")); action_Import_Torrent->setIcon(misc::getIcon("document-import")); + menuAuto_Shutdown_on_downloads_completion->setIcon(misc::getIcon("application-exit")); QMenu *startAllMenu = new QMenu(this); startAllMenu->addAction(actionStart_All); @@ -220,8 +221,19 @@ MainWindow::MainWindow(QWidget *parent, QStringList torrentCmdLine) : QMainWindo displaySearchTab(actionSearch_engine->isChecked()); displayRSSTab(actionRSS_Reader->isChecked()); on_actionExecution_Logs_triggered(actionExecution_Logs->isChecked()); - actionShutdown_when_downloads_complete->setChecked(pref.shutdownWhenDownloadsComplete()); - actionShutdown_qBittorrent_when_downloads_complete->setChecked(pref.shutdownqBTWhenDownloadsComplete()); + + // Auto shutdown actions + QActionGroup * autoShutdownGroup = new QActionGroup(this); + autoShutdownGroup->setExclusive(true); + autoShutdownGroup->addAction(actionAutoShutdown_Disabled); + autoShutdownGroup->addAction(actionAutoExit_qBittorrent); + autoShutdownGroup->addAction(actionAutoShutdown_system); + autoShutdownGroup->addAction(actionAutoSuspend_system); + actionAutoExit_qBittorrent->setChecked(pref.shutdownqBTWhenDownloadsComplete()); + actionAutoShutdown_system->setChecked(pref.shutdownWhenDownloadsComplete()); + actionAutoSuspend_system->setChecked(pref.suspendWhenDownloadsComplete()); + if(!autoShutdownGroup->checkedAction()) + actionAutoShutdown_Disabled->setChecked(true); show(); @@ -1179,16 +1191,6 @@ void MainWindow::on_actionTop_tool_bar_triggered() { Preferences().setToolbarDisplayed(is_visible); } -void MainWindow::on_actionShutdown_when_downloads_complete_triggered() { - bool is_checked = static_cast(sender())->isChecked(); - Preferences().setShutdownWhenDownloadsComplete(is_checked); -} - -void MainWindow::on_actionShutdown_qBittorrent_when_downloads_complete_triggered() { - bool is_checked = static_cast(sender())->isChecked(); - Preferences().setShutdownqBTWhenDownloadsComplete(is_checked); -} - void MainWindow::on_actionSpeed_in_title_bar_triggered() { displaySpeedInTitle = static_cast(sender())->isChecked(); Preferences().showSpeedInTitleBar(displaySpeedInTitle); @@ -1279,3 +1281,21 @@ void MainWindow::on_actionExecution_Logs_triggered(bool checked) } Preferences().setExecutionLogEnabled(checked); } + +void MainWindow::on_actionAutoExit_qBittorrent_toggled(bool enabled) +{ + qDebug() << Q_FUNC_INFO << enabled; + Preferences().setShutdownqBTWhenDownloadsComplete(enabled); +} + +void MainWindow::on_actionAutoSuspend_system_toggled(bool enabled) +{ + qDebug() << Q_FUNC_INFO << enabled; + Preferences().setSuspendWhenDownloadsComplete(enabled); +} + +void MainWindow::on_actionAutoShutdown_system_toggled(bool enabled) +{ + qDebug() << Q_FUNC_INFO << enabled; + Preferences().setShutdownWhenDownloadsComplete(enabled); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 0d39d2e91..12276b7b6 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -187,11 +187,12 @@ private slots: void on_actionRSS_Reader_triggered(); void on_actionSpeed_in_title_bar_triggered(); void on_actionTop_tool_bar_triggered(); - void on_actionShutdown_when_downloads_complete_triggered(); - void on_actionShutdown_qBittorrent_when_downloads_complete_triggered(); void on_action_Import_Torrent_triggered(); void on_actionDonate_money_triggered(); void on_actionExecution_Logs_triggered(bool checked); + void on_actionAutoExit_qBittorrent_toggled(bool ); + void on_actionAutoSuspend_system_toggled(bool ); + void on_actionAutoShutdown_system_toggled(bool ); }; #endif diff --git a/src/mainwindow.ui b/src/mainwindow.ui index d834cf657..2a5ff9c3b 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -59,12 +59,20 @@ &Tools + + + Auto-Shutdown on downloads completion + + + + + + - - + @@ -287,17 +295,6 @@ Search &engine - - - true - - - Shutdown computer when downloads complete - - - Shutdown computer when downloads complete - - Lock qBittorrent @@ -309,14 +306,6 @@ Ctrl+L - - - true - - - Shutdown qBittorrent when downloads complete - - Import existing torrent... @@ -354,6 +343,38 @@ Execution Log + + + true + + + Exit qBittorrent + + + + + true + + + Suspend system + + + + + true + + + Shutdown system + + + + + true + + + Disabled + + diff --git a/src/misc.cpp b/src/misc.cpp index 0d92178b2..2bf4c0fd4 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -46,6 +46,7 @@ #ifdef Q_WS_WIN #include #include +#include const int UNLEN = 256; #else #include @@ -194,15 +195,34 @@ long long misc::freeDiskSpaceOnPath(QString path) { #endif } -void misc::shutdownComputer() { +void suspendComputer() { #ifdef Q_WS_X11 // Use dbus to power off the system // dbus-send --print-reply --system --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown QDBusInterface computer("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); - computer.call("Shutdown"); + computer.call("Suspend", 5); #endif #ifdef Q_WS_MAC - AEEventID EventToSend = kAEShutDown; + +#endif +} + +void misc::shutdownComputer(bool sleep) { +#ifdef Q_WS_X11 + // Use dbus to power off the system + // dbus-send --print-reply --system --dest=org.freedesktop.Hal /org/freedesktop/Hal/devices/computer org.freedesktop.Hal.Device.SystemPowerManagement.Shutdown + QDBusInterface computer("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); + if(sleep) + computer.call("Suspend", 5); + else + computer.call("Shutdown"); +#endif +#ifdef Q_WS_MAC + AEEventID EventToSend; + if(sleep) + EventToSend = kAESleep; + else + EventToSend = kAEShutDown; AEAddressDesc targetDesc; static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess }; AppleEvent eventReply = {typeNull, NULL}; @@ -259,8 +279,11 @@ void misc::shutdownComputer() { if (GetLastError() != ERROR_SUCCESS) return; - bool ret = InitiateSystemShutdownA(0, tr("qBittorrent will shutdown the computer now because all downloads are complete.").toLocal8Bit().data(), 10, true, false); - qDebug("ret: %d", (int)ret); + bool ret; + if(sleep) + SetSuspendState(false, false, false); + else + InitiateSystemShutdownA(0, tr("qBittorrent will shutdown the computer now because all downloads are complete.").toLocal8Bit().data(), 10, true, false); // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; diff --git a/src/misc.h b/src/misc.h index 4052a7b35..00b5aff88 100644 --- a/src/misc.h +++ b/src/misc.h @@ -137,7 +137,7 @@ public: return extension; } - static void shutdownComputer(); + static void shutdownComputer(bool sleep=false); static bool safeRemove(QString file_path) { QFile MyFile(file_path); diff --git a/src/preferences/preferences.h b/src/preferences/preferences.h index 262cc1bdb..26cc47524 100644 --- a/src/preferences/preferences.h +++ b/src/preferences/preferences.h @@ -739,6 +739,14 @@ public: setValue(QString::fromUtf8("Preferences/Downloads/AutoShutDownOnCompletion"), shutdown); } + bool suspendWhenDownloadsComplete() const { + return value(QString::fromUtf8("Preferences/Downloads/AutoSuspendOnCompletion"), false).toBool(); + } + + void setSuspendWhenDownloadsComplete(bool suspend) { + setValue(QString::fromUtf8("Preferences/Downloads/AutoSuspendOnCompletion"), suspend); + } + bool shutdownqBTWhenDownloadsComplete() const { return value(QString::fromUtf8("Preferences/Downloads/AutoShutDownqBTOnCompletion"), false).toBool(); } diff --git a/src/qtlibtorrent/qbtsession.cpp b/src/qtlibtorrent/qbtsession.cpp index 2768a036c..45a960263 100644 --- a/src/qtlibtorrent/qbtsession.cpp +++ b/src/qtlibtorrent/qbtsession.cpp @@ -1950,8 +1950,10 @@ void QBtSession::readAlerts() { qDebug("Emitting finishedTorrent() signal"); emit finishedTorrent(h); qDebug("Received finished alert for %s", qPrintable(h.name())); - bool will_shutdown = (pref.shutdownWhenDownloadsComplete() || pref.shutdownqBTWhenDownloadsComplete()) - && !hasDownloadingTorrents(); + bool will_shutdown = (pref.shutdownWhenDownloadsComplete() || + pref.shutdownqBTWhenDownloadsComplete() || + pref.suspendWhenDownloadsComplete()) + && !hasDownloadingTorrents(); // AutoRun program if(pref.isAutoRunEnabled()) autoRunExternalProgram(h, will_shutdown); @@ -1960,10 +1962,13 @@ void QBtSession::readAlerts() { sendNotificationEmail(h); // Auto-Shutdown if(will_shutdown) { - if(pref.shutdownWhenDownloadsComplete()) { + bool suspend = pref.suspendWhenDownloadsComplete(); + bool shutdown = pref.shutdownWhenDownloadsComplete(); + if(suspend || shutdown) { qDebug("Preparing for auto-shutdown because all downloads are complete!"); // Disabling it for next time pref.setShutdownWhenDownloadsComplete(false); + pref.setSuspendWhenDownloadsComplete(false); #if LIBTORRENT_VERSION_MINOR < 15 saveDHTEntry(); #endif @@ -1971,8 +1976,8 @@ void QBtSession::readAlerts() { saveSessionState(); qDebug("Saving fast resume data"); saveFastResumeData(); - qDebug("Sending computer shutdown signal"); - misc::shutdownComputer(); + qDebug("Sending computer shutdown/suspend signal"); + misc::shutdownComputer(suspend); } qDebug("Exiting the application"); qApp->exit(); diff --git a/winconf.pri b/winconf.pri index 456f00522..546b1a1e9 100644 --- a/winconf.pri +++ b/winconf.pri @@ -49,6 +49,7 @@ debug { LIBS += advapi32.lib shell32.lib LIBS += libeay32MD.lib ssleay32MD.lib +LIBS += PowrProf.lib DEFINES += WITH_GEOIP_EMBEDDED message("On Windows, GeoIP database must be embedded.")