diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index 761e5b8ac..1ed6f6517 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -1250,6 +1250,10 @@ void OptionsDialog::on_buttonBox_accepted() m_ui->tabSelection->setCurrentRow(TAB_WEBUI); return; } + if (!isAlternativeWebUIPathValid()) { + m_ui->tabSelection->setCurrentRow(TAB_WEBUI); + return; + } m_applyButton->setEnabled(false); this->hide(); saveOptions(); @@ -1269,6 +1273,10 @@ void OptionsDialog::applySettings(QAbstractButton *button) m_ui->tabSelection->setCurrentRow(TAB_WEBUI); return; } + if (!isAlternativeWebUIPathValid()) { + m_ui->tabSelection->setCurrentRow(TAB_WEBUI); + return; + } saveOptions(); } } @@ -1751,6 +1759,15 @@ bool OptionsDialog::webUIAuthenticationOk() return true; } +bool OptionsDialog::isAlternativeWebUIPathValid() +{ + if (m_ui->groupAltWebUI->isChecked() && m_ui->textWebUIRootFolder->selectedPath().trimmed().isEmpty()) { + QMessageBox::warning(this, tr("Location Error"), tr("The alternative Web UI files location cannot be blank.")); + return false; + } + return true; +} + void OptionsDialog::on_banListButton_clicked() { // call dialog window diff --git a/src/gui/optionsdialog.h b/src/gui/optionsdialog.h index 37d475c50..7ab204c6e 100644 --- a/src/gui/optionsdialog.h +++ b/src/gui/optionsdialog.h @@ -172,6 +172,7 @@ private: bool setSslCertificate(const QByteArray &cert); bool schedTimesOk(); bool webUIAuthenticationOk(); + bool isAlternativeWebUIPathValid(); QByteArray m_sslCert, m_sslKey; diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 7d4f83231..8d4fb7c88 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -941,7 +941,7 @@ - When Category changed: + When Category Save Path changed: diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index 7fad40bed..bc3539035 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -52,6 +52,7 @@ #include "base/rss/rss_autodownloader.h" #include "base/rss/rss_session.h" #include "base/scanfoldersmodel.h" +#include "base/torrentfileguard.h" #include "base/utils/fs.h" #include "base/utils/net.h" #include "base/utils/password.h" @@ -84,12 +85,23 @@ void AppController::preferencesAction() QVariantMap data; // Downloads - // Hard Disk + // When adding a torrent + data["create_subfolder_enabled"] = session->isCreateTorrentSubfolder(); + data["start_paused_enabled"] = session->isAddTorrentPaused(); + data["auto_delete_mode"] = static_cast(TorrentFileGuard::autoDeleteMode()); + data["preallocate_all"] = session->isPreallocationEnabled(); + data["incomplete_files_ext"] = session->isAppendExtensionEnabled(); + // Saving Management + data["auto_tmm_enabled"] = !session->isAutoTMMDisabledByDefault(); + data["torrent_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenCategoryChanged(); + data["save_path_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenDefaultSavePathChanged(); + data["category_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenCategorySavePathChanged(); data["save_path"] = Utils::Fs::toNativePath(session->defaultSavePath()); data["temp_path_enabled"] = session->isTempPathEnabled(); data["temp_path"] = Utils::Fs::toNativePath(session->tempPath()); - data["preallocate_all"] = session->isPreallocationEnabled(); - data["incomplete_files_ext"] = session->isAppendExtensionEnabled(); + data["export_dir"] = Utils::Fs::toNativePath(session->torrentExportDirectory()); + data["export_dir_fin"] = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory()); + // Automatically add torrents from const QVariantHash dirs = pref->getScanDirs(); QVariantMap nativeDirs; for (QVariantHash::const_iterator i = dirs.cbegin(), e = dirs.cend(); i != e; ++i) { @@ -99,10 +111,9 @@ void AppController::preferencesAction() nativeDirs.insert(Utils::Fs::toNativePath(i.key()), Utils::Fs::toNativePath(i.value().toString())); } data["scan_dirs"] = nativeDirs; - data["export_dir"] = Utils::Fs::toNativePath(session->torrentExportDirectory()); - data["export_dir_fin"] = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory()); // Email notification upon download completion data["mail_notification_enabled"] = pref->isMailNotificationEnabled(); + data["mail_notification_sender"] = pref->getMailNotificationSender(); data["mail_notification_email"] = pref->getMailNotificationEmail(); data["mail_notification_smtp"] = pref->getMailNotificationSMTP(); data["mail_notification_ssl_enabled"] = pref->getMailNotificationSMTPSSL(); @@ -153,6 +164,7 @@ void AppController::preferencesAction() data["bittorrent_protocol"] = static_cast(session->btProtocol()); data["limit_utp_rate"] = session->isUTPRateLimited(); data["limit_tcp_overhead"] = session->includeOverheadInLimits(); + data["limit_lan_peers"] = !session->ignoreLimitsOnLAN(); // Scheduling data["scheduler_enabled"] = session->isBandwidthSchedulerEnabled(); const QTime start_time = pref->getSchedulerStartTime(); @@ -176,6 +188,9 @@ void AppController::preferencesAction() data["max_active_torrents"] = session->maxActiveTorrents(); data["max_active_uploads"] = session->maxActiveUploads(); data["dont_count_slow_torrents"] = session->ignoreSlowTorrentsForQueueing(); + data["slow_torrent_dl_rate_threshold"] = session->downloadRateForSlowTorrents(); + data["slow_torrent_ul_rate_threshold"] = session->uploadRateForSlowTorrents(); + data["slow_torrent_inactive_timer"] = session->slowTorrentsInactivityTimer(); // Share Ratio Limiting data["max_ratio_enabled"] = (session->globalMaxRatio() >= 0.); data["max_ratio"] = session->globalMaxRatio(); @@ -205,6 +220,9 @@ void AppController::preferencesAction() for (const Utils::Net::Subnet &subnet : asConst(pref->getWebUiAuthSubnetWhitelist())) authSubnetWhitelistStringList << Utils::Net::subnetToString(subnet); data["bypass_auth_subnet_whitelist"] = authSubnetWhitelistStringList.join("\n"); + // Use alternative Web UI + data["alternative_webui_enabled"] = pref->isAltWebUiEnabled(); + data["alternative_webui_path"] = pref->getWebUiRootFolder(); // Security data["web_ui_clickjacking_protection_enabled"] = pref->isWebUiClickjackingProtectionEnabled(); data["web_ui_csrf_protection_enabled"] = pref->isWebUiCSRFProtectionEnabled(); @@ -232,19 +250,42 @@ void AppController::setPreferencesAction() Preferences *const pref = Preferences::instance(); auto session = BitTorrent::Session::instance(); const QVariantMap m = QJsonDocument::fromJson(params()["json"].toUtf8()).toVariant().toMap(); + QVariantMap::ConstIterator it; // Downloads - // Hard Disk + // When adding a torrent + if ((it = m.find(QLatin1String("create_subfolder_enabled"))) != m.constEnd()) + session->setCreateTorrentSubfolder(it.value().toBool()); + if ((it = m.find(QLatin1String("start_paused_enabled"))) != m.constEnd()) + session->setAddTorrentPaused(it.value().toBool()); + if ((it = m.find(QLatin1String("auto_delete_mode"))) != m.constEnd()) + TorrentFileGuard::setAutoDeleteMode(static_cast(it.value().toInt())); + + if ((it = m.find(QLatin1String("preallocate_all"))) != m.constEnd()) + session->setPreallocationEnabled(it.value().toBool()); + if ((it = m.find(QLatin1String("incomplete_files_ext"))) != m.constEnd()) + session->setAppendExtensionEnabled(it.value().toBool()); + + // Saving Management + if ((it = m.find(QLatin1String("auto_tmm_enabled"))) != m.constEnd()) + session->setAutoTMMDisabledByDefault(!it.value().toBool()); + if ((it = m.find(QLatin1String("torrent_changed_tmm_enabled"))) != m.constEnd()) + session->setDisableAutoTMMWhenCategoryChanged(!it.value().toBool()); + if ((it = m.find(QLatin1String("save_path_changed_tmm_enabled"))) != m.constEnd()) + session->setDisableAutoTMMWhenDefaultSavePathChanged(!it.value().toBool()); + if ((it = m.find(QLatin1String("category_changed_tmm_enabled"))) != m.constEnd()) + session->setDisableAutoTMMWhenCategorySavePathChanged(!it.value().toBool()); if (m.contains("save_path")) session->setDefaultSavePath(m["save_path"].toString()); if (m.contains("temp_path_enabled")) session->setTempPathEnabled(m["temp_path_enabled"].toBool()); if (m.contains("temp_path")) session->setTempPath(m["temp_path"].toString()); - if (m.contains("preallocate_all")) - session->setPreallocationEnabled(m["preallocate_all"].toBool()); - if (m.contains("incomplete_files_ext")) - session->setAppendExtensionEnabled(m["incomplete_files_ext"].toBool()); + if ((it = m.find(QLatin1String("export_dir"))) != m.constEnd()) + session->setTorrentExportDirectory(it.value().toString()); + if ((it = m.find(QLatin1String("export_dir_fin"))) != m.constEnd()) + session->setFinishedTorrentExportDirectory(it.value().toString()); + // Automatically add torrents from if (m.contains("scan_dirs")) { const QVariantMap nativeDirs = m["scan_dirs"].toMap(); QVariantHash oldScanDirs = pref->getScanDirs(); @@ -288,13 +329,11 @@ void AppController::setPreferencesAction() } pref->setScanDirs(scanDirs); } - if (m.contains("export_dir")) - session->setTorrentExportDirectory(m["export_dir"].toString()); - if (m.contains("export_dir_fin")) - session->setFinishedTorrentExportDirectory(m["export_dir_fin"].toString()); // Email notification upon download completion if (m.contains("mail_notification_enabled")) pref->setMailNotificationEnabled(m["mail_notification_enabled"].toBool()); + if ((it = m.find(QLatin1String("mail_notification_sender"))) != m.constEnd()) + pref->setMailNotificationSender(it.value().toString()); if (m.contains("mail_notification_email")) pref->setMailNotificationEmail(m["mail_notification_email"].toString()); if (m.contains("mail_notification_smtp")) @@ -379,6 +418,8 @@ void AppController::setPreferencesAction() session->setUTPRateLimited(m["limit_utp_rate"].toBool()); if (m.contains("limit_tcp_overhead")) session->setIncludeOverheadInLimits(m["limit_tcp_overhead"].toBool()); + if ((it = m.find(QLatin1String("limit_lan_peers"))) != m.constEnd()) + session->setIgnoreLimitsOnLAN(!it.value().toBool()); // Scheduling if (m.contains("scheduler_enabled")) session->setBandwidthSchedulerEnabled(m["scheduler_enabled"].toBool()); @@ -412,6 +453,12 @@ void AppController::setPreferencesAction() session->setMaxActiveUploads(m["max_active_uploads"].toInt()); if (m.contains("dont_count_slow_torrents")) session->setIgnoreSlowTorrentsForQueueing(m["dont_count_slow_torrents"].toBool()); + if ((it = m.find(QLatin1String("slow_torrent_dl_rate_threshold"))) != m.constEnd()) + session->setDownloadRateForSlowTorrents(it.value().toInt()); + if ((it = m.find(QLatin1String("slow_torrent_ul_rate_threshold"))) != m.constEnd()) + session->setUploadRateForSlowTorrents(it.value().toInt()); + if ((it = m.find(QLatin1String("slow_torrent_inactive_timer"))) != m.constEnd()) + session->setSlowTorrentsInactivityTimer(it.value().toInt()); // Share Ratio Limiting if (m.contains("max_ratio_enabled")) { if (m["max_ratio_enabled"].toBool()) @@ -483,6 +530,11 @@ void AppController::setPreferencesAction() // recognize new lines and commas as delimiters pref->setWebUiAuthSubnetWhitelist(m["bypass_auth_subnet_whitelist"].toString().split(QRegularExpression("\n|,"), QString::SkipEmptyParts)); } + // Use alternative Web UI + if ((it = m.find(QLatin1String("alternative_webui_enabled"))) != m.constEnd()) + pref->setAltWebUiEnabled(it.value().toBool()); + if ((it = m.find(QLatin1String("alternative_webui_path"))) != m.constEnd()) + pref->setWebUiRootFolder(it.value().toString()); // Security if (m.contains("web_ui_clickjacking_protection_enabled")) pref->setWebUiClickjackingProtectionEnabled(m["web_ui_clickjacking_protection_enabled"].toBool()); @@ -505,7 +557,6 @@ void AppController::setPreferencesAction() // Save preferences pref->apply(); - QVariantMap::ConstIterator it; if ((it = m.find(QLatin1String("rss_refresh_interval"))) != m.constEnd()) RSS::Session::instance()->setRefreshInterval(it.value().toUInt()); if ((it = m.find(QLatin1String("rss_max_articles_per_feed"))) != m.constEnd()) diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 1082f829d..c25c75790 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -469,6 +469,7 @@ void TorrentsController::addAction() const QString torrentName = params()["rename"].trimmed(); const int upLimit = params()["upLimit"].toInt(); const int dlLimit = params()["dlLimit"].toInt(); + const TriStateBool autoTMM = parseTriStateBool(params()["autoTMM"]); QList cookies; if (!cookie.isEmpty()) { @@ -496,6 +497,7 @@ void TorrentsController::addAction() params.name = torrentName; params.uploadLimit = (upLimit > 0) ? upLimit : -1; params.downloadLimit = (dlLimit > 0) ? dlLimit : -1; + params.useAutoTMM = autoTMM; bool partialSuccess = false; for (QString url : asConst(urls.split('\n'))) { diff --git a/src/webui/www/private/css/style.css b/src/webui/www/private/css/style.css index c47a6a758..8a1555c24 100644 --- a/src/webui/www/private/css/style.css +++ b/src/webui/www/private/css/style.css @@ -375,28 +375,8 @@ fieldset.settings label { padding: 2px; } -fieldset.settings .leftLabelSmall { - width: 5em; - float: left; - text-align: right; - margin-right: 0.5em; - display: block; -} - -fieldset.settings .leftLabelMedium { - width: 9em; - float: left; - text-align: right; - margin-right: 0.5em; - display: block; -} - -fieldset.settings .leftLabelLarge { - width: 14em; - float: left; - text-align: right; - margin-right: 0.5em; - display: block; +fieldset.settings + div.formRow { + margin-top: 10px; } div.formRow { diff --git a/src/webui/www/private/download.html b/src/webui/www/private/download.html index a2312ddc8..6b89a3ce8 100644 --- a/src/webui/www/private/download.html +++ b/src/webui/www/private/download.html @@ -18,52 +18,114 @@

QBT_TR(Download Torrents from their URLs or Magnet links)QBT_TR[CONTEXT=HttpServer]

QBT_TR(Only one link per line)QBT_TR[CONTEXT=HttpServer]

-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+ + +
+
+ + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
diff --git a/src/webui/www/private/preferences_content.html b/src/webui/www/private/preferences_content.html index fd66f593a..2ae863e93 100644 --- a/src/webui/www/private/preferences_content.html +++ b/src/webui/www/private/preferences_content.html @@ -1,21 +1,120 @@
- QBT_TR(Hard Disk)QBT_TR[CONTEXT=HttpServer] + QBT_TR(When adding a torrent)QBT_TR[CONTEXT=OptionsDialog]
- - + +
- - - + +
+
+ + +
+
+ +
-
+ +
+
-

QBT_TR(Automatically add torrents from:)QBT_TR[CONTEXT=OptionsDialog]
+ +
+ +
+ QBT_TR(Saving Management)QBT_TR[CONTEXT=HttpServer] + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + + + + + + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+
+ +
+ QBT_TR(Automatically add torrents from:)QBT_TR[CONTEXT=OptionsDialog] @@ -34,48 +133,83 @@ - + Add -

- -    -
- -    -
+
- - -
- -
-
- -
+ + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
- -
- -
-
- -
+ + + + + + + + + + + + + +
+ + + +
+ + + +
- - -
+ + + + +
+ +
QBT_TR(Supported parameters (case sensitive):)QBT_TR[CONTEXT=OptionsDialog]
  • QBT_TR(%N: Torrent name)QBT_TR[CONTEXT=OptionsDialog]
  • @@ -95,20 +229,29 @@
-
-
+