From f04b114b643a7026ec6d7c6e5a03e49b57169221 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Sat, 26 Apr 2025 09:27:22 +0300 Subject: [PATCH 01/18] Don't interpret wildcard pattern as filepath globbing PR #22590. Closes #22583. --- src/base/utils/string.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/base/utils/string.cpp b/src/base/utils/string.cpp index f3fc4d87e..1fc6568f8 100644 --- a/src/base/utils/string.cpp +++ b/src/base/utils/string.cpp @@ -61,7 +61,12 @@ QString Utils::String::fromLocal8Bit(const std::string_view string) QString Utils::String::wildcardToRegexPattern(const QString &pattern) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) + return QRegularExpression::wildcardToRegularExpression(pattern + , (QRegularExpression::UnanchoredWildcardConversion | QRegularExpression::NonPathWildcardConversion)); +#else return QRegularExpression::wildcardToRegularExpression(pattern, QRegularExpression::UnanchoredWildcardConversion); +#endif } QStringList Utils::String::splitCommand(const QString &command) From 3fd05d001f6a802a956b2bfa6ec882a36c918dee Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Sat, 26 Apr 2025 09:28:24 +0300 Subject: [PATCH 02/18] Fix appearance of search history length spinbox PR #22605. --- src/gui/optionsdialog.ui | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 71906f13b..cca9436c3 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -3283,15 +3283,9 @@ Disable encryption: Only connect to peers without protocol encryption - - QAbstractSpinBox::ButtonSymbols::PlusMinus - 99 - - QAbstractSpinBox::StepType::DefaultStepType - From a721540e6c8a4a57045ca147eeb102c3f1149b3a Mon Sep 17 00:00:00 2001 From: Isak05 <51046377+Isak05@users.noreply.github.com> Date: Sun, 27 Apr 2025 09:02:52 +0200 Subject: [PATCH 03/18] Fix preview not opening on Wayland Deferring the opening of the preview slightly gives the preview select dialog time to close and for focus to shift back to the main window. PR #22608. Closes #22607. --------- Co-authored-by: Vladimir Golovnev --- src/gui/transferlistwidget.cpp | 20 ++++++++++++-------- src/gui/transferlistwidget.h | 1 + 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index cd6b44653..f553f5c6b 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -311,10 +311,7 @@ void TransferListWidget::torrentDoubleClicked() case PREVIEW_FILE: if (torrentContainsPreviewableFiles(torrent)) { - auto *dialog = new PreviewSelectDialog(this, torrent); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile); - dialog->show(); + openPreviewSelectDialog(torrent); } else { @@ -616,10 +613,7 @@ void TransferListWidget::previewSelectedTorrents() { if (torrentContainsPreviewableFiles(torrent)) { - auto *dialog = new PreviewSelectDialog(this, torrent); - dialog->setAttribute(Qt::WA_DeleteOnClose); - connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile); - dialog->show(); + openPreviewSelectDialog(torrent); } else { @@ -1448,3 +1442,13 @@ void TransferListWidget::wheelEvent(QWheelEvent *event) QTreeView::wheelEvent(event); // event delegated to base class } + +void TransferListWidget::openPreviewSelectDialog(const BitTorrent::Torrent *torrent) +{ + auto *dialog = new PreviewSelectDialog(this, torrent); + dialog->setAttribute(Qt::WA_DeleteOnClose); + // Qt::QueuedConnection is required to prevent a bug on wayland compositors where the preview won't open. + // It occurs when the window focus shifts immediately after TransferListWidget::previewFile has been called. + connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile, Qt::QueuedConnection); + dialog->show(); +} diff --git a/src/gui/transferlistwidget.h b/src/gui/transferlistwidget.h index c5b24ba24..097dd809a 100644 --- a/src/gui/transferlistwidget.h +++ b/src/gui/transferlistwidget.h @@ -123,6 +123,7 @@ private: void dragMoveEvent(QDragMoveEvent *event) override; void dropEvent(QDropEvent *event) override; void wheelEvent(QWheelEvent *event) override; + void openPreviewSelectDialog(const BitTorrent::Torrent *torrent); QModelIndex mapToSource(const QModelIndex &index) const; QModelIndexList mapToSource(const QModelIndexList &indexes) const; QModelIndex mapFromSource(const QModelIndex &index) const; From f4e6b515c2f485f6901b32fbde70d36a630fe253 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Thu, 1 May 2025 08:57:10 +0300 Subject: [PATCH 04/18] Remove dubious seeding time max value PR #22624. --- src/base/bittorrent/sessionimpl.cpp | 17 +++++++++-------- src/base/bittorrent/torrent.cpp | 2 -- src/base/bittorrent/torrent.h | 2 -- src/base/bittorrent/torrentimpl.cpp | 4 ---- src/webui/www/private/shareratio.html | 4 ++-- src/webui/www/private/views/preferences.html | 20 ++++++++++---------- 6 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 4dee5a911..bc3625281 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -467,9 +467,11 @@ SessionImpl::SessionImpl(QObject *parent) , m_additionalTrackers(BITTORRENT_SESSION_KEY(u"AdditionalTrackers"_s)) , m_isAddTrackersFromURLEnabled(BITTORRENT_SESSION_KEY(u"AddTrackersFromURLEnabled"_s), false) , m_additionalTrackersURL(BITTORRENT_SESSION_KEY(u"AdditionalTrackersURL"_s)) - , m_globalMaxRatio(BITTORRENT_SESSION_KEY(u"GlobalMaxRatio"_s), -1, [](qreal r) { return r < 0 ? -1. : r;}) - , m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s), -1, lowerLimited(-1)) - , m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s), -1, lowerLimited(-1)) + , m_globalMaxRatio(BITTORRENT_SESSION_KEY(u"GlobalMaxRatio"_s), -1, [](qreal r) { return r < 0 ? -1. : r; }) + , m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s) + , Torrent::NO_SEEDING_TIME_LIMIT, lowerLimited(Torrent::NO_SEEDING_TIME_LIMIT)) + , m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s) + , Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT, lowerLimited(Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT)) , m_isAddTorrentToQueueTop(BITTORRENT_SESSION_KEY(u"AddTorrentToTopOfQueue"_s), false) , m_isAddTorrentStopped(BITTORRENT_SESSION_KEY(u"AddTorrentStopped"_s), false) , m_torrentStopCondition(BITTORRENT_SESSION_KEY(u"TorrentStopCondition"_s), Torrent::StopCondition::None) @@ -1236,8 +1238,7 @@ int SessionImpl::globalMaxSeedingMinutes() const void SessionImpl::setGlobalMaxSeedingMinutes(int minutes) { - if (minutes < 0) - minutes = -1; + minutes = std::max(minutes, Torrent::NO_SEEDING_TIME_LIMIT); if (minutes != globalMaxSeedingMinutes()) { @@ -1253,7 +1254,7 @@ int SessionImpl::globalMaxInactiveSeedingMinutes() const void SessionImpl::setGlobalMaxInactiveSeedingMinutes(int minutes) { - minutes = std::max(minutes, -1); + minutes = std::max(minutes, Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT); if (minutes != globalMaxInactiveSeedingMinutes()) { @@ -2318,13 +2319,13 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent) description = tr("Torrent reached the share ratio limit."); } else if (const qlonglong seedingTimeInMinutes = torrent->finishedTime() / 60; - (seedingTimeLimit >= 0) && (seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit)) + (seedingTimeLimit >= 0) && (seedingTimeInMinutes >= seedingTimeLimit)) { reached = true; description = tr("Torrent reached the seeding time limit."); } else if (const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60; - (inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit)) + (inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit)) { reached = true; description = tr("Torrent reached the inactive seeding time limit."); diff --git a/src/base/bittorrent/torrent.cpp b/src/base/bittorrent/torrent.cpp index c92fb9aea..1fdf52f61 100644 --- a/src/base/bittorrent/torrent.cpp +++ b/src/base/bittorrent/torrent.cpp @@ -52,8 +52,6 @@ namespace BitTorrent const int Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT = -1; const qreal Torrent::MAX_RATIO = 9999; - const int Torrent::MAX_SEEDING_TIME = 525600; - const int Torrent::MAX_INACTIVE_SEEDING_TIME = 525600; TorrentID Torrent::id() const { diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index d2eefbabf..72cbf0a38 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -132,8 +132,6 @@ namespace BitTorrent static const int NO_INACTIVE_SEEDING_TIME_LIMIT; static const qreal MAX_RATIO; - static const int MAX_SEEDING_TIME; - static const int MAX_INACTIVE_SEEDING_TIME; using TorrentContentHandler::TorrentContentHandler; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 45cc7f3bf..e0fcef23f 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -2727,8 +2727,6 @@ void TorrentImpl::setSeedingTimeLimit(int limit) { if (limit < USE_GLOBAL_SEEDING_TIME) limit = NO_SEEDING_TIME_LIMIT; - else if (limit > MAX_SEEDING_TIME) - limit = MAX_SEEDING_TIME; if (m_seedingTimeLimit != limit) { @@ -2742,8 +2740,6 @@ void TorrentImpl::setInactiveSeedingTimeLimit(int limit) { if (limit < USE_GLOBAL_INACTIVE_SEEDING_TIME) limit = NO_INACTIVE_SEEDING_TIME_LIMIT; - else if (limit > MAX_INACTIVE_SEEDING_TIME) - limit = MAX_SEEDING_TIME; if (m_inactiveSeedingTimeLimit != limit) { diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html index b106e72b8..3c86576e7 100644 --- a/src/webui/www/private/shareratio.html +++ b/src/webui/www/private/shareratio.html @@ -177,12 +177,12 @@
- +
- +
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 727eb318d..51feaafcd 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -2887,11 +2887,11 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["max_ratio_enabled"] = $("max_ratio_checkbox").checked; settings["max_ratio"] = max_ratio; - let max_seeding_time = -1; - if ($("max_seeding_time_checkbox").checked) { - max_seeding_time = Number($("max_seeding_time_value").value); - if (isNaN(max_seeding_time) || (max_seeding_time < 0) || (max_seeding_time > 525600)) { - alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]"); + let maxSeedingTime = -1; + if (document.getElementById("maxSeedingTimeCheckbox").checked) { + maxSeedingTime = Number(document.getElementById("maxSeedingTimeValue").value); + if (Number.isNaN(maxSeedingTime) || (maxSeedingTime < 0)) { + alert("QBT_TR(Seeding time limit must not have a negative value.)QBT_TR[CONTEXT=HttpServer]"); return; } } @@ -2899,11 +2899,11 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD settings["max_seeding_time"] = max_seeding_time; settings["max_ratio_act"] = Number($("max_ratio_act").value); - let max_inactive_seeding_time = -1; - if ($("max_inactive_seeding_time_checkbox").checked) { - max_inactive_seeding_time = Number($("max_inactive_seeding_time_value").value); - if (isNaN(max_inactive_seeding_time) || (max_inactive_seeding_time < 0) || (max_inactive_seeding_time > 525600)) { - alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]"); + let maxInactiveSeedingTime = -1; + if (document.getElementById("maxInactiveSeedingTimeCheckbox").checked) { + maxInactiveSeedingTime = Number(document.getElementById("maxInactiveSeedingTimeValue").value); + if (Number.isNaN(maxInactiveSeedingTime) || (maxInactiveSeedingTime < 0)) { + alert("QBT_TR(Seeding time limit must not have a negative value.)QBT_TR[CONTEXT=HttpServer]"); return; } } From b3690494abc112298611693b8da8b9a37d9f7bdd Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Thu, 1 May 2025 14:18:18 +0300 Subject: [PATCH 05/18] Fix ratio handling PR #22638. --- src/base/bittorrent/sessionimpl.cpp | 4 ++-- src/base/bittorrent/torrent.cpp | 4 +++- src/base/bittorrent/torrentimpl.cpp | 5 ++--- src/gui/optionsdialog.ui | 3 --- src/gui/properties/propertieswidget.cpp | 4 ++-- src/gui/torrentsharelimitswidget.ui | 3 --- src/gui/transferlistmodel.cpp | 2 +- src/webui/api/serialize/serialize_torrent.cpp | 2 +- src/webui/api/torrentscontroller.cpp | 4 ++-- src/webui/www/private/shareratio.html | 2 +- src/webui/www/private/views/preferences.html | 10 +++++----- 11 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index bc3625281..2c1ad188a 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1222,7 +1222,7 @@ qreal SessionImpl::globalMaxRatio() const void SessionImpl::setGlobalMaxRatio(qreal ratio) { if (ratio < 0) - ratio = -1.; + ratio = Torrent::NO_RATIO_LIMIT; if (ratio != globalMaxRatio()) { @@ -2313,7 +2313,7 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent) QString description; if (const qreal ratio = torrent->realRatio(); - (ratioLimit >= 0) && (ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit)) + (ratioLimit >= 0) && (ratio >= ratioLimit)) { reached = true; description = tr("Torrent reached the share ratio limit."); diff --git a/src/base/bittorrent/torrent.cpp b/src/base/bittorrent/torrent.cpp index 1fdf52f61..b8098d77f 100644 --- a/src/base/bittorrent/torrent.cpp +++ b/src/base/bittorrent/torrent.cpp @@ -29,6 +29,8 @@ #include "torrent.h" +#include + #include #include "infohash.h" @@ -51,7 +53,7 @@ namespace BitTorrent const int Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME = -2; const int Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT = -1; - const qreal Torrent::MAX_RATIO = 9999; + const qreal Torrent::MAX_RATIO = std::numeric_limits::infinity(); TorrentID Torrent::id() const { diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index e0fcef23f..96547fe77 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1549,7 +1549,8 @@ qreal TorrentImpl::realRatio() const const qreal ratio = upload / static_cast(download); Q_ASSERT(ratio >= 0); - return (ratio > MAX_RATIO) ? MAX_RATIO : ratio; + + return ratio; } int TorrentImpl::uploadPayloadRate() const @@ -2712,8 +2713,6 @@ void TorrentImpl::setRatioLimit(qreal limit) { if (limit < USE_GLOBAL_RATIO) limit = NO_RATIO_LIMIT; - else if (limit > MAX_RATIO) - limit = MAX_RATIO; if (m_ratioLimit != limit) { diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index cca9436c3..4d124915f 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -3021,9 +3021,6 @@ Disable encryption: Only connect to peers without protocol encryption false - - 9998.000000000000000 - 0.050000000000000 diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index d5c2b03a4..fe7870272 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -439,10 +439,10 @@ void PropertiesWidget::loadDynamicData() // Update ratio info const qreal ratio = m_torrent->realRatio(); - m_ui->labelShareRatioVal->setText(ratio > BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(ratio, 2)); + m_ui->labelShareRatioVal->setText(ratio >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(ratio, 2)); const qreal popularity = m_torrent->popularity(); - m_ui->labelPopularityVal->setText(popularity > BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 2)); + m_ui->labelPopularityVal->setText(popularity >= BitTorrent::Torrent::MAX_RATIO ? C_INFINITY : Utils::String::fromDouble(popularity, 2)); m_ui->labelSeedsVal->setText(tr("%1 (%2 total)", "%1 and %2 are numbers, e.g. 3 (10 total)") .arg(QString::number(m_torrent->seedsCount()) diff --git a/src/gui/torrentsharelimitswidget.ui b/src/gui/torrentsharelimitswidget.ui index 9ada9ed67..13fbfe0a2 100644 --- a/src/gui/torrentsharelimitswidget.ui +++ b/src/gui/torrentsharelimitswidget.ui @@ -47,9 +47,6 @@ false - - 9998.000000000000000 - 0.050000000000000 diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp index 7c827c1a6..0298db047 100644 --- a/src/gui/transferlistmodel.cpp +++ b/src/gui/transferlistmodel.cpp @@ -293,7 +293,7 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons if (hideValues && (value <= 0)) return {}; - return ((static_cast(value) == -1) || (value > BitTorrent::Torrent::MAX_RATIO)) + return ((static_cast(value) == -1) || (value >= BitTorrent::Torrent::MAX_RATIO)) ? C_INFINITY : Utils::String::fromDouble(value, 2); }; diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp index bc75a7698..1543170d4 100644 --- a/src/webui/api/serialize/serialize_torrent.cpp +++ b/src/webui/api/serialize/serialize_torrent.cpp @@ -96,7 +96,7 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent) const auto adjustRatio = [](const qreal ratio) -> qreal { - return (ratio > BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio; + return (ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio; }; const auto getLastActivityTime = [&torrent]() -> qlonglong diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 324bb89d6..39e536867 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -522,8 +522,8 @@ void TorrentsController::propertiesAction() {KEY_PROP_SEEDS_TOTAL, torrent->totalSeedsCount()}, {KEY_PROP_PEERS, torrent->leechsCount()}, {KEY_PROP_PEERS_TOTAL, torrent->totalLeechersCount()}, - {KEY_PROP_RATIO, ((ratio > BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)}, - {KEY_PROP_POPULARITY, ((popularity > BitTorrent::Torrent::MAX_RATIO) ? -1 : popularity)}, + {KEY_PROP_RATIO, ((ratio >= BitTorrent::Torrent::MAX_RATIO) ? -1 : ratio)}, + {KEY_PROP_POPULARITY, ((popularity >= BitTorrent::Torrent::MAX_RATIO) ? -1 : popularity)}, {KEY_PROP_REANNOUNCE, torrent->nextAnnounce()}, {KEY_PROP_TOTAL_SIZE, torrent->totalSize()}, {KEY_PROP_PIECES_NUM, torrent->piecesCount()}, diff --git a/src/webui/www/private/shareratio.html b/src/webui/www/private/shareratio.html index 3c86576e7..10f5a0bd7 100644 --- a/src/webui/www/private/shareratio.html +++ b/src/webui/www/private/shareratio.html @@ -172,7 +172,7 @@
- +
diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 51feaafcd..fb1a06833 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -2876,11 +2876,11 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD } // Share Ratio Limiting - let max_ratio = -1; - if ($("max_ratio_checkbox").checked) { - max_ratio = Number($("max_ratio_value").value); - if (isNaN(max_ratio) || (max_ratio < 0) || (max_ratio > 9998)) { - alert("QBT_TR(Share ratio limit must be between 0 and 9998.)QBT_TR[CONTEXT=HttpServer]"); + let maxRatio = -1; + if (document.getElementById("maxRatioCheckbox").checked) { + maxRatio = Number(document.getElementById("maxRatioValue").value); + if (isNaN(maxRatio) || (maxRatio < 0)) { + alert("QBT_TR(Share ratio limit must not have a negative value.)QBT_TR[CONTEXT=HttpServer]"); return; } } From 87b90b7fd7b9e4b48b4da932b747d2bec9610e87 Mon Sep 17 00:00:00 2001 From: dezza <402927+dezza@users.noreply.github.com> Date: Sat, 10 May 2025 10:48:05 +0200 Subject: [PATCH 06/18] WebUI: Remove `unselectable` from General tab Making General-tab text `unselectable` is not an improvement. It begs to add a new `Copy -> Save path` feature, because using `Set location` to copy save path (*which requires a request*) is not faster than simply copying it from the `General` tab by double-left clicking and pressing `CTRL+C`. I don't see a reason why its necessary to software-restrict people from copying details from the `General`-tab - there are several reasons why you would - incl. the above mentioned usecase for quickly copying save-path, but other than that its counterproductive to limit people from copying the details displayed. PR #22663. --- src/webui/www/private/views/properties.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webui/www/private/views/properties.html b/src/webui/www/private/views/properties.html index e3cb42b1b..fbcaa1d53 100644 --- a/src/webui/www/private/views/properties.html +++ b/src/webui/www/private/views/properties.html @@ -1,4 +1,4 @@ -