mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-22 00:17:23 -06:00
committed by
GitHub
parent
1c231ce014
commit
b5d16dfeee
@@ -32,7 +32,7 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
|
||||||
#include "base/bittorrent/sharelimitaction.h"
|
#include "base/bittorrent/sharelimits.h"
|
||||||
#include "base/bittorrent/torrentcontentlayout.h"
|
#include "base/bittorrent/torrentcontentlayout.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ add_library(qbt_base STATIC
|
|||||||
bittorrent/session.h
|
bittorrent/session.h
|
||||||
bittorrent/sessionimpl.h
|
bittorrent/sessionimpl.h
|
||||||
bittorrent/sessionstatus.h
|
bittorrent/sessionstatus.h
|
||||||
bittorrent/sharelimitaction.h
|
bittorrent/sharelimits.h
|
||||||
bittorrent/speedmonitor.h
|
bittorrent/speedmonitor.h
|
||||||
bittorrent/sslparameters.h
|
bittorrent/sslparameters.h
|
||||||
bittorrent/torrent.h
|
bittorrent/torrent.h
|
||||||
|
|||||||
@@ -125,9 +125,9 @@ BitTorrent::AddTorrentParams BitTorrent::parseAddTorrentParams(const QJsonObject
|
|||||||
.useAutoTMM = getOptionalBool(jsonObj, PARAM_AUTOTMM),
|
.useAutoTMM = getOptionalBool(jsonObj, PARAM_AUTOTMM),
|
||||||
.uploadLimit = jsonObj.value(PARAM_UPLOADLIMIT).toInt(-1),
|
.uploadLimit = jsonObj.value(PARAM_UPLOADLIMIT).toInt(-1),
|
||||||
.downloadLimit = jsonObj.value(PARAM_DOWNLOADLIMIT).toInt(-1),
|
.downloadLimit = jsonObj.value(PARAM_DOWNLOADLIMIT).toInt(-1),
|
||||||
.seedingTimeLimit = jsonObj.value(PARAM_SEEDINGTIMELIMIT).toInt(Torrent::USE_GLOBAL_SEEDING_TIME),
|
.seedingTimeLimit = jsonObj.value(PARAM_SEEDINGTIMELIMIT).toInt(DEFAULT_SEEDING_TIME_LIMIT),
|
||||||
.inactiveSeedingTimeLimit = jsonObj.value(PARAM_INACTIVESEEDINGTIMELIMIT).toInt(Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME),
|
.inactiveSeedingTimeLimit = jsonObj.value(PARAM_INACTIVESEEDINGTIMELIMIT).toInt(DEFAULT_SEEDING_TIME_LIMIT),
|
||||||
.ratioLimit = jsonObj.value(PARAM_RATIOLIMIT).toDouble(Torrent::USE_GLOBAL_RATIO),
|
.ratioLimit = jsonObj.value(PARAM_RATIOLIMIT).toDouble(DEFAULT_RATIO_LIMIT),
|
||||||
.shareLimitAction = getEnum<ShareLimitAction>(jsonObj, PARAM_SHARELIMITACTION, ShareLimitAction::Default),
|
.shareLimitAction = getEnum<ShareLimitAction>(jsonObj, PARAM_SHARELIMITACTION, ShareLimitAction::Default),
|
||||||
.sslParameters =
|
.sslParameters =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
#include "base/tagset.h"
|
#include "base/tagset.h"
|
||||||
#include "sharelimitaction.h"
|
#include "sharelimits.h"
|
||||||
#include "sslparameters.h"
|
#include "sslparameters.h"
|
||||||
#include "torrent.h"
|
#include "torrent.h"
|
||||||
#include "torrentcontentlayout.h"
|
#include "torrentcontentlayout.h"
|
||||||
@@ -68,9 +68,9 @@ namespace BitTorrent
|
|||||||
std::optional<bool> useAutoTMM;
|
std::optional<bool> useAutoTMM;
|
||||||
int uploadLimit = -1;
|
int uploadLimit = -1;
|
||||||
int downloadLimit = -1;
|
int downloadLimit = -1;
|
||||||
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
int inactiveSeedingTimeLimit = Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
int inactiveSeedingTimeLimit = DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
qreal ratioLimit = DEFAULT_RATIO_LIMIT;
|
||||||
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
||||||
SSLParameters sslParameters;
|
SSLParameters sslParameters;
|
||||||
|
|
||||||
|
|||||||
@@ -239,8 +239,8 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorre
|
|||||||
torrentParams.comment = fromLTString(resumeDataRoot.dict_find_string_value("qBt-comment"));
|
torrentParams.comment = fromLTString(resumeDataRoot.dict_find_string_value("qBt-comment"));
|
||||||
torrentParams.hasFinishedStatus = resumeDataRoot.dict_find_int_value("qBt-seedStatus");
|
torrentParams.hasFinishedStatus = resumeDataRoot.dict_find_int_value("qBt-seedStatus");
|
||||||
torrentParams.firstLastPiecePriority = resumeDataRoot.dict_find_int_value("qBt-firstLastPiecePriority");
|
torrentParams.firstLastPiecePriority = resumeDataRoot.dict_find_int_value("qBt-firstLastPiecePriority");
|
||||||
torrentParams.seedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-seedingTimeLimit", Torrent::USE_GLOBAL_SEEDING_TIME);
|
torrentParams.seedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-seedingTimeLimit", DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
torrentParams.inactiveSeedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-inactiveSeedingTimeLimit", Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
torrentParams.inactiveSeedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-inactiveSeedingTimeLimit", DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
torrentParams.shareLimitAction = Utils::String::toEnum(
|
torrentParams.shareLimitAction = Utils::String::toEnum(
|
||||||
fromLTString(resumeDataRoot.dict_find_string_value("qBt-shareLimitAction")), ShareLimitAction::Default);
|
fromLTString(resumeDataRoot.dict_find_string_value("qBt-shareLimitAction")), ShareLimitAction::Default);
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorre
|
|||||||
|
|
||||||
const lt::string_view ratioLimitString = resumeDataRoot.dict_find_string_value("qBt-ratioLimit");
|
const lt::string_view ratioLimitString = resumeDataRoot.dict_find_string_value("qBt-ratioLimit");
|
||||||
if (ratioLimitString.empty())
|
if (ratioLimitString.empty())
|
||||||
torrentParams.ratioLimit = resumeDataRoot.dict_find_int_value("qBt-ratioLimit", Torrent::USE_GLOBAL_RATIO * 1000) / 1000.0;
|
torrentParams.ratioLimit = resumeDataRoot.dict_find_int_value("qBt-ratioLimit", DEFAULT_RATIO_LIMIT * 1000) / 1000.0;
|
||||||
else
|
else
|
||||||
torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble();
|
torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2021-2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2021-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -32,10 +32,16 @@
|
|||||||
#include <QJsonValue>
|
#include <QJsonValue>
|
||||||
|
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
|
#include "base/utils/string.h"
|
||||||
|
|
||||||
const QString OPTION_SAVEPATH = u"save_path"_s;
|
const QString OPTION_SAVEPATH = u"save_path"_s;
|
||||||
const QString OPTION_DOWNLOADPATH = u"download_path"_s;
|
const QString OPTION_DOWNLOADPATH = u"download_path"_s;
|
||||||
|
|
||||||
|
const QString OPTION_RATIOLIMIT = u"ratio_limit"_s;
|
||||||
|
const QString OPTION_SEEDINGTIMELIMIT = u"seeding_time_limit"_s;
|
||||||
|
const QString OPTION_INACTIVESEEDINGTIMELIMIT = u"inactive_seeding_time_limit"_s;
|
||||||
|
const QString OPTION_SHARELIMITACTION = u"share_limit_action"_s;
|
||||||
|
|
||||||
BitTorrent::CategoryOptions BitTorrent::CategoryOptions::fromJSON(const QJsonObject &jsonObj)
|
BitTorrent::CategoryOptions BitTorrent::CategoryOptions::fromJSON(const QJsonObject &jsonObj)
|
||||||
{
|
{
|
||||||
CategoryOptions options;
|
CategoryOptions options;
|
||||||
@@ -47,6 +53,11 @@ BitTorrent::CategoryOptions BitTorrent::CategoryOptions::fromJSON(const QJsonObj
|
|||||||
else if (downloadPathValue.isString())
|
else if (downloadPathValue.isString())
|
||||||
options.downloadPath = {true, Path(downloadPathValue.toString())};
|
options.downloadPath = {true, Path(downloadPathValue.toString())};
|
||||||
|
|
||||||
|
options.ratioLimit = jsonObj.value(OPTION_RATIOLIMIT).toDouble(DEFAULT_RATIO_LIMIT);
|
||||||
|
options.seedingTimeLimit = jsonObj.value(OPTION_SEEDINGTIMELIMIT).toInt(DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
|
options.inactiveSeedingTimeLimit = jsonObj.value(OPTION_INACTIVESEEDINGTIMELIMIT).toInt(DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
|
options.shareLimitAction = Utils::String::toEnum<ShareLimitAction>(jsonObj.value(OPTION_SHARELIMITACTION).toString(), ShareLimitAction::Default);
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,12 +74,10 @@ QJsonObject BitTorrent::CategoryOptions::toJSON() const
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
{OPTION_SAVEPATH, savePath.data()},
|
{OPTION_SAVEPATH, savePath.data()},
|
||||||
{OPTION_DOWNLOADPATH, downloadPathValue}
|
{OPTION_DOWNLOADPATH, downloadPathValue},
|
||||||
|
{OPTION_RATIOLIMIT, ratioLimit},
|
||||||
|
{OPTION_SEEDINGTIMELIMIT, seedingTimeLimit},
|
||||||
|
{OPTION_INACTIVESEEDINGTIMELIMIT, inactiveSeedingTimeLimit},
|
||||||
|
{OPTION_SHARELIMITACTION, Utils::String::fromEnum(shareLimitAction)}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitTorrent::operator==(const BitTorrent::CategoryOptions &left, const BitTorrent::CategoryOptions &right)
|
|
||||||
{
|
|
||||||
return ((left.savePath == right.savePath)
|
|
||||||
&& (left.downloadPath == right.downloadPath));
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2021-2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2021-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
#include "downloadpathoption.h"
|
#include "downloadpathoption.h"
|
||||||
|
#include "sharelimits.h"
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
|
|
||||||
@@ -44,9 +45,14 @@ namespace BitTorrent
|
|||||||
Path savePath;
|
Path savePath;
|
||||||
std::optional<DownloadPathOption> downloadPath;
|
std::optional<DownloadPathOption> downloadPath;
|
||||||
|
|
||||||
|
qreal ratioLimit = DEFAULT_RATIO_LIMIT;
|
||||||
|
int seedingTimeLimit = DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
|
int inactiveSeedingTimeLimit = DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
|
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
||||||
|
|
||||||
static CategoryOptions fromJSON(const QJsonObject &jsonObj);
|
static CategoryOptions fromJSON(const QJsonObject &jsonObj);
|
||||||
QJsonObject toJSON() const;
|
QJsonObject toJSON() const;
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const CategoryOptions &left, const CategoryOptions &right);
|
friend bool operator==(const CategoryOptions &, const CategoryOptions &) = default;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
#include "base/tagset.h"
|
#include "base/tagset.h"
|
||||||
#include "sharelimitaction.h"
|
#include "sharelimits.h"
|
||||||
#include "sslparameters.h"
|
#include "sslparameters.h"
|
||||||
#include "torrent.h"
|
#include "torrent.h"
|
||||||
#include "torrentcontentlayout.h"
|
#include "torrentcontentlayout.h"
|
||||||
@@ -61,9 +61,9 @@ namespace BitTorrent
|
|||||||
|
|
||||||
bool addToQueueTop = false; // only for new torrents
|
bool addToQueueTop = false; // only for new torrents
|
||||||
|
|
||||||
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
qreal ratioLimit = DEFAULT_RATIO_LIMIT;
|
||||||
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
int inactiveSeedingTimeLimit = Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
int inactiveSeedingTimeLimit = DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
||||||
|
|
||||||
SSLParameters sslParameters;
|
SSLParameters sslParameters;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "addtorrenterror.h"
|
#include "addtorrenterror.h"
|
||||||
#include "addtorrentparams.h"
|
#include "addtorrentparams.h"
|
||||||
#include "categoryoptions.h"
|
#include "categoryoptions.h"
|
||||||
#include "sharelimitaction.h"
|
#include "sharelimits.h"
|
||||||
#include "torrentcontentremoveoption.h"
|
#include "torrentcontentremoveoption.h"
|
||||||
#include "trackerentry.h"
|
#include "trackerentry.h"
|
||||||
#include "trackerentrystatus.h"
|
#include "trackerentrystatus.h"
|
||||||
@@ -158,12 +158,16 @@ namespace BitTorrent
|
|||||||
|
|
||||||
virtual QStringList categories() const = 0;
|
virtual QStringList categories() const = 0;
|
||||||
virtual CategoryOptions categoryOptions(const QString &categoryName) const = 0;
|
virtual CategoryOptions categoryOptions(const QString &categoryName) const = 0;
|
||||||
|
virtual bool setCategoryOptions(const QString &categoryName, const CategoryOptions &options) = 0;
|
||||||
virtual Path categorySavePath(const QString &categoryName) const = 0;
|
virtual Path categorySavePath(const QString &categoryName) const = 0;
|
||||||
virtual Path categorySavePath(const QString &categoryName, const CategoryOptions &options) const = 0;
|
virtual Path categorySavePath(const QString &categoryName, const CategoryOptions &options) const = 0;
|
||||||
virtual Path categoryDownloadPath(const QString &categoryName) const = 0;
|
virtual Path categoryDownloadPath(const QString &categoryName) const = 0;
|
||||||
virtual Path categoryDownloadPath(const QString &categoryName, const CategoryOptions &options) const = 0;
|
virtual Path categoryDownloadPath(const QString &categoryName, const CategoryOptions &options) const = 0;
|
||||||
|
virtual qreal categoryRatioLimit(const QString &categoryName) const = 0;
|
||||||
|
virtual int categorySeedingTimeLimit(const QString &categoryName) const = 0;
|
||||||
|
virtual int categoryInactiveSeedingTimeLimit(const QString &categoryName) const = 0;
|
||||||
|
virtual ShareLimitAction categoryShareLimitAction(const QString &categoryName) const = 0;
|
||||||
virtual bool addCategory(const QString &name, const CategoryOptions &options = {}) = 0;
|
virtual bool addCategory(const QString &name, const CategoryOptions &options = {}) = 0;
|
||||||
virtual bool editCategory(const QString &name, const CategoryOptions &options) = 0;
|
|
||||||
virtual bool removeCategory(const QString &name) = 0;
|
virtual bool removeCategory(const QString &name) = 0;
|
||||||
virtual bool useCategoryPathsInManualMode() const = 0;
|
virtual bool useCategoryPathsInManualMode() const = 0;
|
||||||
virtual void setUseCategoryPathsInManualMode(bool value) = 0;
|
virtual void setUseCategoryPathsInManualMode(bool value) = 0;
|
||||||
|
|||||||
@@ -513,9 +513,9 @@ SessionImpl::SessionImpl(QObject *parent)
|
|||||||
, m_additionalTrackersURL(BITTORRENT_SESSION_KEY(u"AdditionalTrackersURL"_s))
|
, 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_globalMaxRatio(BITTORRENT_SESSION_KEY(u"GlobalMaxRatio"_s), -1, [](qreal r) { return r < 0 ? -1. : r; })
|
||||||
, m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s)
|
, m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s)
|
||||||
, Torrent::NO_SEEDING_TIME_LIMIT, lowerLimited(Torrent::NO_SEEDING_TIME_LIMIT))
|
, NO_SEEDING_TIME_LIMIT, lowerLimited(NO_SEEDING_TIME_LIMIT))
|
||||||
, m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s)
|
, m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s)
|
||||||
, Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT, lowerLimited(Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT))
|
, NO_SEEDING_TIME_LIMIT, lowerLimited(NO_SEEDING_TIME_LIMIT))
|
||||||
, m_isAddTorrentToQueueTop(BITTORRENT_SESSION_KEY(u"AddTorrentToTopOfQueue"_s), false)
|
, m_isAddTorrentToQueueTop(BITTORRENT_SESSION_KEY(u"AddTorrentToTopOfQueue"_s), false)
|
||||||
, m_isAddTorrentStopped(BITTORRENT_SESSION_KEY(u"AddTorrentStopped"_s), false)
|
, m_isAddTorrentStopped(BITTORRENT_SESSION_KEY(u"AddTorrentStopped"_s), false)
|
||||||
, m_torrentStopCondition(BITTORRENT_SESSION_KEY(u"TorrentStopCondition"_s), Torrent::StopCondition::None)
|
, m_torrentStopCondition(BITTORRENT_SESSION_KEY(u"TorrentStopCondition"_s), Torrent::StopCondition::None)
|
||||||
@@ -972,6 +972,62 @@ Path SessionImpl::categoryDownloadPath(const QString &categoryName, const Catego
|
|||||||
return (basePath / path);
|
return (basePath / path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal SessionImpl::categoryRatioLimit(const QString &categoryName) const
|
||||||
|
{
|
||||||
|
if (categoryName.isEmpty())
|
||||||
|
return globalMaxRatio();
|
||||||
|
|
||||||
|
if (const auto ratioLimit = categoryOptions(categoryName).ratioLimit;
|
||||||
|
ratioLimit != DEFAULT_RATIO_LIMIT)
|
||||||
|
{
|
||||||
|
return ratioLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return categoryRatioLimit(parentCategoryName(categoryName));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SessionImpl::categorySeedingTimeLimit(const QString &categoryName) const
|
||||||
|
{
|
||||||
|
if (categoryName.isEmpty())
|
||||||
|
return globalMaxSeedingMinutes();
|
||||||
|
|
||||||
|
if (const auto seedingTimeLimit = categoryOptions(categoryName).seedingTimeLimit;
|
||||||
|
seedingTimeLimit != DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
|
{
|
||||||
|
return seedingTimeLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return categorySeedingTimeLimit(parentCategoryName(categoryName));
|
||||||
|
}
|
||||||
|
|
||||||
|
int SessionImpl::categoryInactiveSeedingTimeLimit(const QString &categoryName) const
|
||||||
|
{
|
||||||
|
if (categoryName.isEmpty())
|
||||||
|
return globalMaxInactiveSeedingMinutes();
|
||||||
|
|
||||||
|
if (const auto inactiveSeedingTimeLimit = categoryOptions(categoryName).inactiveSeedingTimeLimit;
|
||||||
|
inactiveSeedingTimeLimit != DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
|
{
|
||||||
|
return inactiveSeedingTimeLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return categoryInactiveSeedingTimeLimit(parentCategoryName(categoryName));
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareLimitAction SessionImpl::categoryShareLimitAction(const QString &categoryName) const
|
||||||
|
{
|
||||||
|
if (categoryName.isEmpty())
|
||||||
|
return shareLimitAction();
|
||||||
|
|
||||||
|
if (const auto shareLimitAction = categoryOptions(categoryName).shareLimitAction;
|
||||||
|
shareLimitAction != ShareLimitAction::Default)
|
||||||
|
{
|
||||||
|
return shareLimitAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return categoryShareLimitAction(parentCategoryName(categoryName));
|
||||||
|
}
|
||||||
|
|
||||||
DownloadPathOption SessionImpl::resolveCategoryDownloadPathOption(const QString &categoryName, const std::optional<DownloadPathOption> &option) const
|
DownloadPathOption SessionImpl::resolveCategoryDownloadPathOption(const QString &categoryName, const std::optional<DownloadPathOption> &option) const
|
||||||
{
|
{
|
||||||
if (categoryName.isEmpty())
|
if (categoryName.isEmpty())
|
||||||
@@ -1008,9 +1064,9 @@ bool SessionImpl::addCategory(const QString &name, const CategoryOptions &option
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionImpl::editCategory(const QString &name, const CategoryOptions &options)
|
bool SessionImpl::setCategoryOptions(const QString &categoryName, const CategoryOptions &options)
|
||||||
{
|
{
|
||||||
const auto it = m_categories.find(name);
|
const auto it = m_categories.find(categoryName);
|
||||||
if (it == m_categories.end())
|
if (it == m_categories.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -1018,14 +1074,15 @@ bool SessionImpl::editCategory(const QString &name, const CategoryOptions &optio
|
|||||||
if (options == currentOptions)
|
if (options == currentOptions)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (isDisableAutoTMMWhenCategorySavePathChanged())
|
if (isDisableAutoTMMWhenCategorySavePathChanged()
|
||||||
|
&& ((options.savePath != currentOptions.savePath) || (options.downloadPath != currentOptions.downloadPath)))
|
||||||
{
|
{
|
||||||
// This should be done before changing the category options
|
// This should be done before changing the category options
|
||||||
// to prevent the torrent from being moved at the new save path.
|
// to prevent the torrent from being moved at the new save path.
|
||||||
|
|
||||||
for (TorrentImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
{
|
{
|
||||||
if (torrent->category() == name)
|
if (torrent->category() == categoryName)
|
||||||
torrent->setAutoTMMEnabled(false);
|
torrent->setAutoTMMEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1035,11 +1092,11 @@ bool SessionImpl::editCategory(const QString &name, const CategoryOptions &optio
|
|||||||
|
|
||||||
for (TorrentImpl *const torrent : asConst(m_torrents))
|
for (TorrentImpl *const torrent : asConst(m_torrents))
|
||||||
{
|
{
|
||||||
if (torrent->category() == name)
|
if (torrent->category() == categoryName)
|
||||||
torrent->handleCategoryOptionsChanged();
|
torrent->handleCategoryOptionsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit categoryOptionsChanged(name);
|
emit categoryOptionsChanged(categoryName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1235,7 +1292,7 @@ qreal SessionImpl::globalMaxRatio() const
|
|||||||
void SessionImpl::setGlobalMaxRatio(qreal ratio)
|
void SessionImpl::setGlobalMaxRatio(qreal ratio)
|
||||||
{
|
{
|
||||||
if (ratio < 0)
|
if (ratio < 0)
|
||||||
ratio = Torrent::NO_RATIO_LIMIT;
|
ratio = NO_RATIO_LIMIT;
|
||||||
|
|
||||||
if (ratio != globalMaxRatio())
|
if (ratio != globalMaxRatio())
|
||||||
{
|
{
|
||||||
@@ -1251,7 +1308,7 @@ int SessionImpl::globalMaxSeedingMinutes() const
|
|||||||
|
|
||||||
void SessionImpl::setGlobalMaxSeedingMinutes(int minutes)
|
void SessionImpl::setGlobalMaxSeedingMinutes(int minutes)
|
||||||
{
|
{
|
||||||
minutes = std::max(minutes, Torrent::NO_SEEDING_TIME_LIMIT);
|
minutes = std::max(minutes, NO_SEEDING_TIME_LIMIT);
|
||||||
|
|
||||||
if (minutes != globalMaxSeedingMinutes())
|
if (minutes != globalMaxSeedingMinutes())
|
||||||
{
|
{
|
||||||
@@ -1267,7 +1324,7 @@ int SessionImpl::globalMaxInactiveSeedingMinutes() const
|
|||||||
|
|
||||||
void SessionImpl::setGlobalMaxInactiveSeedingMinutes(int minutes)
|
void SessionImpl::setGlobalMaxInactiveSeedingMinutes(int minutes)
|
||||||
{
|
{
|
||||||
minutes = std::max(minutes, Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT);
|
minutes = std::max(minutes, NO_SEEDING_TIME_LIMIT);
|
||||||
|
|
||||||
if (minutes != globalMaxInactiveSeedingMinutes())
|
if (minutes != globalMaxInactiveSeedingMinutes())
|
||||||
{
|
{
|
||||||
@@ -2310,14 +2367,9 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent)
|
|||||||
if (!torrent->isFinished() || torrent->isForced())
|
if (!torrent->isFinished() || torrent->isForced())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto effectiveLimit = []<typename T>(const T limit, const T useGlobalLimit, const T globalLimit) -> T
|
const qreal ratioLimit = torrent->effectiveRatioLimit();
|
||||||
{
|
const int seedingTimeLimit = torrent->effectiveSeedingTimeLimit();
|
||||||
return (limit == useGlobalLimit) ? globalLimit : limit;
|
const int inactiveSeedingTimeLimit = torrent->effectiveInactiveSeedingTimeLimit();
|
||||||
};
|
|
||||||
|
|
||||||
const qreal ratioLimit = effectiveLimit(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
|
|
||||||
const int seedingTimeLimit = effectiveLimit(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
|
|
||||||
const int inactiveSeedingTimeLimit = effectiveLimit(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
|
|
||||||
|
|
||||||
bool reached = false;
|
bool reached = false;
|
||||||
QString description;
|
QString description;
|
||||||
@@ -2344,7 +2396,7 @@ void SessionImpl::processTorrentShareLimits(TorrentImpl *torrent)
|
|||||||
if (reached)
|
if (reached)
|
||||||
{
|
{
|
||||||
const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
|
const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
|
||||||
const ShareLimitAction shareLimitAction = (torrent->shareLimitAction() == ShareLimitAction::Default) ? m_shareLimitAction : torrent->shareLimitAction();
|
const ShareLimitAction shareLimitAction = torrent->effectiveShareLimitAction();
|
||||||
|
|
||||||
if (shareLimitAction == ShareLimitAction::Remove)
|
if (shareLimitAction == ShareLimitAction::Remove)
|
||||||
{
|
{
|
||||||
@@ -5172,9 +5224,9 @@ bool SessionImpl::isKnownTorrent(const InfoHash &infoHash) const
|
|||||||
|
|
||||||
void SessionImpl::updateSeedingLimitTimer()
|
void SessionImpl::updateSeedingLimitTimer()
|
||||||
{
|
{
|
||||||
if ((globalMaxRatio() == Torrent::NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
|
if ((globalMaxRatio() == NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
|
||||||
&& (globalMaxSeedingMinutes() == Torrent::NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit()
|
&& (globalMaxSeedingMinutes() == NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit()
|
||||||
&& (globalMaxInactiveSeedingMinutes() == Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT) && !hasPerTorrentInactiveSeedingTimeLimit())
|
&& (globalMaxInactiveSeedingMinutes() == NO_SEEDING_TIME_LIMIT) && !hasPerTorrentInactiveSeedingTimeLimit())
|
||||||
{
|
{
|
||||||
if (m_seedingLimitTimer->isActive())
|
if (m_seedingLimitTimer->isActive())
|
||||||
m_seedingLimitTimer->stop();
|
m_seedingLimitTimer->stop();
|
||||||
|
|||||||
@@ -149,12 +149,16 @@ namespace BitTorrent
|
|||||||
|
|
||||||
QStringList categories() const override;
|
QStringList categories() const override;
|
||||||
CategoryOptions categoryOptions(const QString &categoryName) const override;
|
CategoryOptions categoryOptions(const QString &categoryName) const override;
|
||||||
|
bool setCategoryOptions(const QString &categoryName, const CategoryOptions &options) override;
|
||||||
Path categorySavePath(const QString &categoryName) const override;
|
Path categorySavePath(const QString &categoryName) const override;
|
||||||
Path categorySavePath(const QString &categoryName, const CategoryOptions &options) const override;
|
Path categorySavePath(const QString &categoryName, const CategoryOptions &options) const override;
|
||||||
Path categoryDownloadPath(const QString &categoryName) const override;
|
Path categoryDownloadPath(const QString &categoryName) const override;
|
||||||
Path categoryDownloadPath(const QString &categoryName, const CategoryOptions &options) const override;
|
Path categoryDownloadPath(const QString &categoryName, const CategoryOptions &options) const override;
|
||||||
|
qreal categoryRatioLimit(const QString &categoryName) const override;
|
||||||
|
int categorySeedingTimeLimit(const QString &categoryName) const override;
|
||||||
|
int categoryInactiveSeedingTimeLimit(const QString &categoryName) const override;
|
||||||
|
ShareLimitAction categoryShareLimitAction(const QString &categoryName) const override;
|
||||||
bool addCategory(const QString &name, const CategoryOptions &options = {}) override;
|
bool addCategory(const QString &name, const CategoryOptions &options = {}) override;
|
||||||
bool editCategory(const QString &name, const CategoryOptions &options) override;
|
|
||||||
bool removeCategory(const QString &name) override;
|
bool removeCategory(const QString &name) override;
|
||||||
bool useCategoryPathsInManualMode() const override;
|
bool useCategoryPathsInManualMode() const override;
|
||||||
void setUseCategoryPathsInManualMode(bool value) override;
|
void setUseCategoryPathsInManualMode(bool value) override;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -33,6 +33,12 @@
|
|||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
|
inline const qreal DEFAULT_RATIO_LIMIT = -2;
|
||||||
|
inline const qreal NO_RATIO_LIMIT = -1;
|
||||||
|
|
||||||
|
inline const int DEFAULT_SEEDING_TIME_LIMIT = -2;
|
||||||
|
inline const int NO_SEEDING_TIME_LIMIT = -1;
|
||||||
|
|
||||||
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||||
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||||
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2015-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -44,15 +44,6 @@ namespace BitTorrent
|
|||||||
|
|
||||||
// Torrent
|
// Torrent
|
||||||
|
|
||||||
const qreal Torrent::USE_GLOBAL_RATIO = -2;
|
|
||||||
const qreal Torrent::NO_RATIO_LIMIT = -1;
|
|
||||||
|
|
||||||
const int Torrent::USE_GLOBAL_SEEDING_TIME = -2;
|
|
||||||
const int Torrent::NO_SEEDING_TIME_LIMIT = -1;
|
|
||||||
|
|
||||||
const int Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME = -2;
|
|
||||||
const int Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT = -1;
|
|
||||||
|
|
||||||
const qreal Torrent::MAX_RATIO = std::numeric_limits<qreal>::infinity();
|
const qreal Torrent::MAX_RATIO = std::numeric_limits<qreal>::infinity();
|
||||||
|
|
||||||
TorrentID Torrent::id() const
|
TorrentID Torrent::id() const
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "base/3rdparty/expected.hpp"
|
#include "base/3rdparty/expected.hpp"
|
||||||
#include "base/pathfwd.h"
|
#include "base/pathfwd.h"
|
||||||
#include "base/tagset.h"
|
#include "base/tagset.h"
|
||||||
#include "sharelimitaction.h"
|
#include "sharelimits.h"
|
||||||
#include "torrentannouncestatus.h"
|
#include "torrentannouncestatus.h"
|
||||||
#include "torrentcontenthandler.h"
|
#include "torrentcontenthandler.h"
|
||||||
|
|
||||||
@@ -125,15 +125,6 @@ namespace BitTorrent
|
|||||||
};
|
};
|
||||||
Q_ENUM(StopCondition)
|
Q_ENUM(StopCondition)
|
||||||
|
|
||||||
static const qreal USE_GLOBAL_RATIO;
|
|
||||||
static const qreal NO_RATIO_LIMIT;
|
|
||||||
|
|
||||||
static const int USE_GLOBAL_SEEDING_TIME;
|
|
||||||
static const int NO_SEEDING_TIME_LIMIT;
|
|
||||||
|
|
||||||
static const int USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
|
||||||
static const int NO_INACTIVE_SEEDING_TIME_LIMIT;
|
|
||||||
|
|
||||||
static const qreal MAX_RATIO;
|
static const qreal MAX_RATIO;
|
||||||
|
|
||||||
using TorrentContentHandler::TorrentContentHandler;
|
using TorrentContentHandler::TorrentContentHandler;
|
||||||
@@ -236,6 +227,10 @@ namespace BitTorrent
|
|||||||
virtual void setInactiveSeedingTimeLimit(int limit) = 0;
|
virtual void setInactiveSeedingTimeLimit(int limit) = 0;
|
||||||
virtual ShareLimitAction shareLimitAction() const = 0;
|
virtual ShareLimitAction shareLimitAction() const = 0;
|
||||||
virtual void setShareLimitAction(ShareLimitAction action) = 0;
|
virtual void setShareLimitAction(ShareLimitAction action) = 0;
|
||||||
|
virtual qreal effectiveRatioLimit() const = 0;
|
||||||
|
virtual int effectiveSeedingTimeLimit() const = 0;
|
||||||
|
virtual int effectiveInactiveSeedingTimeLimit() const = 0;
|
||||||
|
virtual ShareLimitAction effectiveShareLimitAction() const = 0;
|
||||||
|
|
||||||
virtual PathList filePaths() const = 0;
|
virtual PathList filePaths() const = 0;
|
||||||
virtual PathList actualFilePaths() const = 0;
|
virtual PathList actualFilePaths() const = 0;
|
||||||
@@ -279,9 +274,6 @@ namespace BitTorrent
|
|||||||
virtual bool isLSDDisabled() const = 0;
|
virtual bool isLSDDisabled() const = 0;
|
||||||
virtual QBitArray pieces() const = 0;
|
virtual QBitArray pieces() const = 0;
|
||||||
virtual qreal distributedCopies() const = 0;
|
virtual qreal distributedCopies() const = 0;
|
||||||
virtual qreal maxRatio() const = 0;
|
|
||||||
virtual int maxSeedingTime() const = 0;
|
|
||||||
virtual int maxInactiveSeedingTime() const = 0;
|
|
||||||
virtual qreal realRatio() const = 0;
|
virtual qreal realRatio() const = 0;
|
||||||
virtual qreal popularity() const = 0;
|
virtual qreal popularity() const = 0;
|
||||||
virtual int uploadPayloadRate() const = 0;
|
virtual int uploadPayloadRate() const = 0;
|
||||||
|
|||||||
@@ -1338,16 +1338,16 @@ qlonglong TorrentImpl::eta() const
|
|||||||
|
|
||||||
if (isFinished())
|
if (isFinished())
|
||||||
{
|
{
|
||||||
const qreal maxRatioValue = maxRatio();
|
const qreal maxRatioValue = effectiveRatioLimit();
|
||||||
const int maxSeedingTimeValue = maxSeedingTime();
|
const int maxSeedingTimeValue = effectiveSeedingTimeLimit();
|
||||||
const int maxInactiveSeedingTimeValue = maxInactiveSeedingTime();
|
const int maxInactiveSeedingTimeValue = effectiveInactiveSeedingTimeLimit();
|
||||||
if ((maxRatioValue < 0) && (maxSeedingTimeValue < 0) && (maxInactiveSeedingTimeValue < 0)) return MAX_ETA;
|
if ((maxRatioValue < 0) && (maxSeedingTimeValue < 0) && (maxInactiveSeedingTimeValue < 0))
|
||||||
|
return MAX_ETA;
|
||||||
|
|
||||||
qlonglong ratioEta = MAX_ETA;
|
qlonglong ratioEta = MAX_ETA;
|
||||||
|
|
||||||
if ((speedAverage.upload > 0) && (maxRatioValue >= 0))
|
if ((speedAverage.upload > 0) && (maxRatioValue >= 0))
|
||||||
{
|
{
|
||||||
|
|
||||||
qlonglong realDL = totalDownload();
|
qlonglong realDL = totalDownload();
|
||||||
if (realDL <= 0)
|
if (realDL <= 0)
|
||||||
realDL = wantedSize();
|
realDL = wantedSize();
|
||||||
@@ -1479,30 +1479,38 @@ qreal TorrentImpl::distributedCopies() const
|
|||||||
return m_nativeStatus.distributed_copies;
|
return m_nativeStatus.distributed_copies;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal TorrentImpl::maxRatio() const
|
qreal TorrentImpl::effectiveRatioLimit() const
|
||||||
{
|
{
|
||||||
if (m_ratioLimit == USE_GLOBAL_RATIO)
|
if (m_ratioLimit == DEFAULT_RATIO_LIMIT)
|
||||||
return m_session->globalMaxRatio();
|
return m_session->categoryRatioLimit(category());
|
||||||
|
|
||||||
return m_ratioLimit;
|
return m_ratioLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TorrentImpl::maxSeedingTime() const
|
int TorrentImpl::effectiveSeedingTimeLimit() const
|
||||||
{
|
{
|
||||||
if (m_seedingTimeLimit == USE_GLOBAL_SEEDING_TIME)
|
if (m_seedingTimeLimit == DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
return m_session->globalMaxSeedingMinutes();
|
return m_session->categorySeedingTimeLimit(category());
|
||||||
|
|
||||||
return m_seedingTimeLimit;
|
return m_seedingTimeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TorrentImpl::maxInactiveSeedingTime() const
|
int TorrentImpl::effectiveInactiveSeedingTimeLimit() const
|
||||||
{
|
{
|
||||||
if (m_inactiveSeedingTimeLimit == USE_GLOBAL_INACTIVE_SEEDING_TIME)
|
if (m_inactiveSeedingTimeLimit == DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
return m_session->globalMaxInactiveSeedingMinutes();
|
return m_session->categoryInactiveSeedingTimeLimit(category());
|
||||||
|
|
||||||
return m_inactiveSeedingTimeLimit;
|
return m_inactiveSeedingTimeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShareLimitAction TorrentImpl::effectiveShareLimitAction() const
|
||||||
|
{
|
||||||
|
if (m_shareLimitAction == ShareLimitAction::Default)
|
||||||
|
return m_session->categoryShareLimitAction(category());
|
||||||
|
|
||||||
|
return m_shareLimitAction;
|
||||||
|
}
|
||||||
|
|
||||||
qreal TorrentImpl::realRatio() const
|
qreal TorrentImpl::realRatio() const
|
||||||
{
|
{
|
||||||
const int64_t upload = m_nativeStatus.all_time_upload;
|
const int64_t upload = m_nativeStatus.all_time_upload;
|
||||||
@@ -2623,7 +2631,7 @@ void TorrentImpl::updateProgress()
|
|||||||
|
|
||||||
void TorrentImpl::setRatioLimit(qreal limit)
|
void TorrentImpl::setRatioLimit(qreal limit)
|
||||||
{
|
{
|
||||||
if (limit < USE_GLOBAL_RATIO)
|
if (limit < DEFAULT_RATIO_LIMIT)
|
||||||
limit = NO_RATIO_LIMIT;
|
limit = NO_RATIO_LIMIT;
|
||||||
|
|
||||||
if (m_ratioLimit != limit)
|
if (m_ratioLimit != limit)
|
||||||
@@ -2636,7 +2644,7 @@ void TorrentImpl::setRatioLimit(qreal limit)
|
|||||||
|
|
||||||
void TorrentImpl::setSeedingTimeLimit(int limit)
|
void TorrentImpl::setSeedingTimeLimit(int limit)
|
||||||
{
|
{
|
||||||
if (limit < USE_GLOBAL_SEEDING_TIME)
|
if (limit < DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
limit = NO_SEEDING_TIME_LIMIT;
|
limit = NO_SEEDING_TIME_LIMIT;
|
||||||
|
|
||||||
if (m_seedingTimeLimit != limit)
|
if (m_seedingTimeLimit != limit)
|
||||||
@@ -2649,8 +2657,8 @@ void TorrentImpl::setSeedingTimeLimit(int limit)
|
|||||||
|
|
||||||
void TorrentImpl::setInactiveSeedingTimeLimit(int limit)
|
void TorrentImpl::setInactiveSeedingTimeLimit(int limit)
|
||||||
{
|
{
|
||||||
if (limit < USE_GLOBAL_INACTIVE_SEEDING_TIME)
|
if (limit < DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
limit = NO_INACTIVE_SEEDING_TIME_LIMIT;
|
limit = NO_SEEDING_TIME_LIMIT;
|
||||||
|
|
||||||
if (m_inactiveSeedingTimeLimit != limit)
|
if (m_inactiveSeedingTimeLimit != limit)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -156,6 +156,10 @@ namespace BitTorrent
|
|||||||
void setInactiveSeedingTimeLimit(int limit) override;
|
void setInactiveSeedingTimeLimit(int limit) override;
|
||||||
ShareLimitAction shareLimitAction() const override;
|
ShareLimitAction shareLimitAction() const override;
|
||||||
void setShareLimitAction(ShareLimitAction action) override;
|
void setShareLimitAction(ShareLimitAction action) override;
|
||||||
|
qreal effectiveRatioLimit() const override;
|
||||||
|
int effectiveSeedingTimeLimit() const override;
|
||||||
|
int effectiveInactiveSeedingTimeLimit() const override;
|
||||||
|
ShareLimitAction effectiveShareLimitAction() const override;
|
||||||
|
|
||||||
Path filePath(int index) const override;
|
Path filePath(int index) const override;
|
||||||
Path actualFilePath(int index) const override;
|
Path actualFilePath(int index) const override;
|
||||||
@@ -205,9 +209,6 @@ namespace BitTorrent
|
|||||||
bool isLSDDisabled() const override;
|
bool isLSDDisabled() const override;
|
||||||
QBitArray pieces() const override;
|
QBitArray pieces() const override;
|
||||||
qreal distributedCopies() const override;
|
qreal distributedCopies() const override;
|
||||||
qreal maxRatio() const override;
|
|
||||||
int maxSeedingTime() const override;
|
|
||||||
int maxInactiveSeedingTime() const override;
|
|
||||||
qreal realRatio() const override;
|
qreal realRatio() const override;
|
||||||
qreal popularity() const override;
|
qreal popularity() const override;
|
||||||
int uploadPayloadRate() const override;
|
int uploadPayloadRate() const override;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -190,6 +190,7 @@ void AddTorrentParamsWidget::populate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
populateDefaultPaths();
|
populateDefaultPaths();
|
||||||
|
resetShareLimitsWidgetDefaults();
|
||||||
});
|
});
|
||||||
|
|
||||||
m_ui->savePathEdit->disconnect(this);
|
m_ui->savePathEdit->disconnect(this);
|
||||||
@@ -270,6 +271,7 @@ void AddTorrentParamsWidget::populate()
|
|||||||
m_addTorrentParams.addToQueueTop = data.toBool();
|
m_addTorrentParams.addToQueueTop = data.toBool();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
resetShareLimitsWidgetDefaults();
|
||||||
m_ui->torrentShareLimitsWidget->setRatioLimit(m_addTorrentParams.ratioLimit);
|
m_ui->torrentShareLimitsWidget->setRatioLimit(m_addTorrentParams.ratioLimit);
|
||||||
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(m_addTorrentParams.seedingTimeLimit);
|
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(m_addTorrentParams.seedingTimeLimit);
|
||||||
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(m_addTorrentParams.inactiveSeedingTimeLimit);
|
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(m_addTorrentParams.inactiveSeedingTimeLimit);
|
||||||
@@ -418,3 +420,11 @@ void AddTorrentParamsWidget::populateSavePathOptions()
|
|||||||
|
|
||||||
populateDefaultPaths();
|
populateDefaultPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddTorrentParamsWidget::resetShareLimitsWidgetDefaults()
|
||||||
|
{
|
||||||
|
const auto *btSession = BitTorrent::Session::instance();
|
||||||
|
m_ui->torrentShareLimitsWidget->setDefaults((m_addTorrentParams.category.isEmpty() ? TorrentShareLimitsWidget::UsedDefaults::Global : TorrentShareLimitsWidget::UsedDefaults::Category)
|
||||||
|
, btSession->categoryRatioLimit(m_addTorrentParams.category), btSession->categorySeedingTimeLimit(m_addTorrentParams.category)
|
||||||
|
, btSession->categoryInactiveSeedingTimeLimit(m_addTorrentParams.category), btSession->categoryShareLimitAction(m_addTorrentParams.category));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2023-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -57,7 +57,7 @@ private:
|
|||||||
void populateDefaultPaths();
|
void populateDefaultPaths();
|
||||||
void populateDefaultDownloadPath();
|
void populateDefaultDownloadPath();
|
||||||
void populateSavePathOptions();
|
void populateSavePathOptions();
|
||||||
|
void resetShareLimitsWidgetDefaults();
|
||||||
|
|
||||||
Ui::AddTorrentParamsWidget *m_ui;
|
Ui::AddTorrentParamsWidget *m_ui;
|
||||||
BitTorrent::AddTorrentParams m_addTorrentParams;
|
BitTorrent::AddTorrentParams m_addTorrentParams;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/sharelimitaction.h"
|
#include "base/bittorrent/sharelimits.h"
|
||||||
#include "base/exceptions.h"
|
#include "base/exceptions.h"
|
||||||
#include "base/global.h"
|
#include "base/global.h"
|
||||||
#include "base/net/downloadmanager.h"
|
#include "base/net/downloadmanager.h"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2017, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2017-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -32,11 +32,12 @@
|
|||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/utils/fs.h"
|
#include "base/bittorrent/torrent.h"
|
||||||
|
#include "torrentsharelimitswidget.h"
|
||||||
#include "ui_torrentcategorydialog.h"
|
#include "ui_torrentcategorydialog.h"
|
||||||
|
|
||||||
TorrentCategoryDialog::TorrentCategoryDialog(QWidget *parent)
|
TorrentCategoryDialog::TorrentCategoryDialog(QWidget *parent)
|
||||||
: QDialog {parent}
|
: QDialog(parent)
|
||||||
, m_ui {new Ui::TorrentCategoryDialog}
|
, m_ui {new Ui::TorrentCategoryDialog}
|
||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
@@ -56,6 +57,15 @@ TorrentCategoryDialog::TorrentCategoryDialog(QWidget *parent)
|
|||||||
|
|
||||||
connect(m_ui->textCategoryName, &QLineEdit::textChanged, this, &TorrentCategoryDialog::categoryNameChanged);
|
connect(m_ui->textCategoryName, &QLineEdit::textChanged, this, &TorrentCategoryDialog::categoryNameChanged);
|
||||||
connect(m_ui->comboUseDownloadPath, &QComboBox::currentIndexChanged, this, &TorrentCategoryDialog::useDownloadPathChanged);
|
connect(m_ui->comboUseDownloadPath, &QComboBox::currentIndexChanged, this, &TorrentCategoryDialog::useDownloadPathChanged);
|
||||||
|
|
||||||
|
resetShareLimitsWidgetDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
TorrentCategoryDialog::TorrentCategoryDialog(QWidget *parent, const QString &categoryName, const BitTorrent::CategoryOptions &categoryOptions)
|
||||||
|
: TorrentCategoryDialog(parent)
|
||||||
|
{
|
||||||
|
setCategoryName(categoryName);
|
||||||
|
setCategoryOptions(categoryOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentCategoryDialog::~TorrentCategoryDialog()
|
TorrentCategoryDialog::~TorrentCategoryDialog()
|
||||||
@@ -73,8 +83,7 @@ QString TorrentCategoryDialog::createCategory(QWidget *parent, const QString &pa
|
|||||||
newCategoryName += u'/';
|
newCategoryName += u'/';
|
||||||
newCategoryName += tr("New Category");
|
newCategoryName += tr("New Category");
|
||||||
|
|
||||||
TorrentCategoryDialog dialog {parent};
|
TorrentCategoryDialog dialog {parent, newCategoryName, {}};
|
||||||
dialog.setCategoryName(newCategoryName);
|
|
||||||
while (dialog.exec() == TorrentCategoryDialog::Accepted)
|
while (dialog.exec() == TorrentCategoryDialog::Accepted)
|
||||||
{
|
{
|
||||||
newCategoryName = dialog.categoryName();
|
newCategoryName = dialog.categoryName();
|
||||||
@@ -110,14 +119,12 @@ void TorrentCategoryDialog::editCategory(QWidget *parent, const QString &categor
|
|||||||
|
|
||||||
Q_ASSERT(Session::instance()->categories().contains(categoryName));
|
Q_ASSERT(Session::instance()->categories().contains(categoryName));
|
||||||
|
|
||||||
auto *dialog = new TorrentCategoryDialog(parent);
|
auto *dialog = new TorrentCategoryDialog(parent, categoryName, Session::instance()->categoryOptions(categoryName));
|
||||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
dialog->setCategoryNameEditable(false);
|
dialog->setCategoryNameEditable(false);
|
||||||
dialog->setCategoryName(categoryName);
|
|
||||||
dialog->setCategoryOptions(Session::instance()->categoryOptions(categoryName));
|
|
||||||
connect(dialog, &TorrentCategoryDialog::accepted, parent, [dialog, categoryName]()
|
connect(dialog, &TorrentCategoryDialog::accepted, parent, [dialog, categoryName]()
|
||||||
{
|
{
|
||||||
Session::instance()->editCategory(categoryName, dialog->categoryOptions());
|
Session::instance()->setCategoryOptions(categoryName, dialog->categoryOptions());
|
||||||
});
|
});
|
||||||
dialog->open();
|
dialog->open();
|
||||||
}
|
}
|
||||||
@@ -149,6 +156,11 @@ BitTorrent::CategoryOptions TorrentCategoryDialog::categoryOptions() const
|
|||||||
else if (m_ui->comboUseDownloadPath->currentIndex() == 2)
|
else if (m_ui->comboUseDownloadPath->currentIndex() == 2)
|
||||||
categoryOptions.downloadPath = {false, {}};
|
categoryOptions.downloadPath = {false, {}};
|
||||||
|
|
||||||
|
categoryOptions.ratioLimit = m_ui->torrentShareLimitsWidget->ratioLimit().value_or(BitTorrent::DEFAULT_RATIO_LIMIT);
|
||||||
|
categoryOptions.seedingTimeLimit = m_ui->torrentShareLimitsWidget->seedingTimeLimit().value_or(BitTorrent::DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
|
categoryOptions.inactiveSeedingTimeLimit = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit().value_or(BitTorrent::DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
|
categoryOptions.shareLimitAction = m_ui->torrentShareLimitsWidget->shareLimitAction().value_or(BitTorrent::ShareLimitAction::Default);
|
||||||
|
|
||||||
return categoryOptions;
|
return categoryOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,6 +177,11 @@ void TorrentCategoryDialog::setCategoryOptions(const BitTorrent::CategoryOptions
|
|||||||
m_ui->comboUseDownloadPath->setCurrentIndex(0);
|
m_ui->comboUseDownloadPath->setCurrentIndex(0);
|
||||||
m_ui->comboDownloadPath->setSelectedPath({});
|
m_ui->comboDownloadPath->setSelectedPath({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_ui->torrentShareLimitsWidget->setRatioLimit(categoryOptions.ratioLimit);
|
||||||
|
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(categoryOptions.seedingTimeLimit);
|
||||||
|
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(categoryOptions.inactiveSeedingTimeLimit);
|
||||||
|
m_ui->torrentShareLimitsWidget->setShareLimitAction(categoryOptions.shareLimitAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentCategoryDialog::categoryNameChanged(const QString &categoryName)
|
void TorrentCategoryDialog::categoryNameChanged(const QString &categoryName)
|
||||||
@@ -177,6 +194,13 @@ void TorrentCategoryDialog::categoryNameChanged(const QString &categoryName)
|
|||||||
if (useDownloadPath)
|
if (useDownloadPath)
|
||||||
m_ui->comboDownloadPath->setPlaceholder(btSession->categoryDownloadPath(categoryName, categoryOptions()));
|
m_ui->comboDownloadPath->setPlaceholder(btSession->categoryDownloadPath(categoryName, categoryOptions()));
|
||||||
|
|
||||||
|
const QString parentCategoryName = BitTorrent::Session::parentCategoryName(categoryName);
|
||||||
|
if (m_parentCategoryName != parentCategoryName)
|
||||||
|
{
|
||||||
|
m_parentCategoryName = parentCategoryName;
|
||||||
|
resetShareLimitsWidgetDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!categoryName.isEmpty());
|
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!categoryName.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,3 +219,11 @@ void TorrentCategoryDialog::useDownloadPathChanged(const int index)
|
|||||||
const Path categoryPath = btSession->categoryDownloadPath(categoryName, categoryOptions());
|
const Path categoryPath = btSession->categoryDownloadPath(categoryName, categoryOptions());
|
||||||
m_ui->comboDownloadPath->setPlaceholder(useDownloadPath ? categoryPath : Path());
|
m_ui->comboDownloadPath->setPlaceholder(useDownloadPath ? categoryPath : Path());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentCategoryDialog::resetShareLimitsWidgetDefaults()
|
||||||
|
{
|
||||||
|
const auto *btSession = BitTorrent::Session::instance();
|
||||||
|
m_ui->torrentShareLimitsWidget->setDefaults((m_parentCategoryName.isEmpty() ? TorrentShareLimitsWidget::UsedDefaults::Global : TorrentShareLimitsWidget::UsedDefaults::Category)
|
||||||
|
, btSession->categoryRatioLimit(m_parentCategoryName), btSession->categorySeedingTimeLimit(m_parentCategoryName)
|
||||||
|
, btSession->categoryInactiveSeedingTimeLimit(m_parentCategoryName), btSession->categoryShareLimitAction(m_parentCategoryName));
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2017, 2021 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2017-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
static void editCategory(QWidget *parent, const QString &categoryName);
|
static void editCategory(QWidget *parent, const QString &categoryName);
|
||||||
|
|
||||||
explicit TorrentCategoryDialog(QWidget *parent = nullptr);
|
explicit TorrentCategoryDialog(QWidget *parent = nullptr);
|
||||||
|
TorrentCategoryDialog(QWidget *parent, const QString &categoryName, const BitTorrent::CategoryOptions &categoryOptions);
|
||||||
~TorrentCategoryDialog() override;
|
~TorrentCategoryDialog() override;
|
||||||
|
|
||||||
void setCategoryNameEditable(bool editable);
|
void setCategoryNameEditable(bool editable);
|
||||||
@@ -65,6 +66,9 @@ private slots:
|
|||||||
void useDownloadPathChanged(int index);
|
void useDownloadPathChanged(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void resetShareLimitsWidgetDefaults();
|
||||||
|
|
||||||
Ui::TorrentCategoryDialog *m_ui = nullptr;
|
Ui::TorrentCategoryDialog *m_ui = nullptr;
|
||||||
Path m_lastEnteredDownloadPath;
|
Path m_lastEnteredDownloadPath;
|
||||||
|
QString m_parentCategoryName;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>493</width>
|
<width>493</width>
|
||||||
<height>208</height>
|
<height>268</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -140,6 +140,18 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="torrentShareLimitsBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Torrent share limits</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="torrentShareLimitsBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="TorrentShareLimitsWidget" name="torrentShareLimitsWidget" native="true"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@@ -172,6 +184,12 @@
|
|||||||
<header>gui/fspathedit.h</header>
|
<header>gui/fspathedit.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TorrentShareLimitsWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>gui/torrentsharelimitswidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
@@ -347,9 +347,9 @@ void TorrentCreatorDialog::handleCreationSuccess(const BitTorrent::TorrentCreato
|
|||||||
params.skipChecking = true;
|
params.skipChecking = true;
|
||||||
if (m_ui->checkIgnoreShareLimits->isChecked())
|
if (m_ui->checkIgnoreShareLimits->isChecked())
|
||||||
{
|
{
|
||||||
params.ratioLimit = BitTorrent::Torrent::NO_RATIO_LIMIT;
|
params.ratioLimit = BitTorrent::NO_RATIO_LIMIT;
|
||||||
params.seedingTimeLimit = BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT;
|
params.seedingTimeLimit = BitTorrent::NO_SEEDING_TIME_LIMIT;
|
||||||
params.inactiveSeedingTimeLimit = BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT;
|
params.inactiveSeedingTimeLimit = BitTorrent::NO_SEEDING_TIME_LIMIT;
|
||||||
}
|
}
|
||||||
params.useAutoTMM = false; // otherwise if it is on by default, it will overwrite `savePath` to the default save path
|
params.useAutoTMM = false; // otherwise if it is on by default, it will overwrite `savePath` to the default save path
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2024-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2020 thalieht
|
* Copyright (C) 2020 thalieht
|
||||||
* Copyright (C) 2011 Christian Kandeler
|
* Copyright (C) 2011 Christian Kandeler
|
||||||
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||||
@@ -289,7 +289,12 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QList<BitTorre
|
|||||||
, this, &TorrentOptionsDialog::handleDownSpeedLimitChanged);
|
, this, &TorrentOptionsDialog::handleDownSpeedLimitChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->torrentShareLimitsWidget->setDefaultLimits(session->globalMaxRatio(), session->globalMaxSeedingMinutes(), session->globalMaxInactiveSeedingMinutes());
|
if (m_allSameCategory)
|
||||||
|
{
|
||||||
|
m_ui->torrentShareLimitsWidget->setDefaults((firstTorrentCategory.isEmpty() ? TorrentShareLimitsWidget::UsedDefaults::Global : TorrentShareLimitsWidget::UsedDefaults::Category)
|
||||||
|
, session->categoryRatioLimit(firstTorrentCategory), session->categorySeedingTimeLimit(firstTorrentCategory)
|
||||||
|
, session->categoryInactiveSeedingTimeLimit(firstTorrentCategory), session->categoryShareLimitAction(firstTorrentCategory));
|
||||||
|
}
|
||||||
if (allSameRatio)
|
if (allSameRatio)
|
||||||
m_ui->torrentShareLimitsWidget->setRatioLimit(firstTorrentRatio);
|
m_ui->torrentShareLimitsWidget->setRatioLimit(firstTorrentRatio);
|
||||||
if (allSameSeedingTime)
|
if (allSameSeedingTime)
|
||||||
@@ -477,30 +482,37 @@ void TorrentOptionsDialog::accept()
|
|||||||
|
|
||||||
void TorrentOptionsDialog::handleCategoryChanged([[maybe_unused]] const int index)
|
void TorrentOptionsDialog::handleCategoryChanged([[maybe_unused]] const int index)
|
||||||
{
|
{
|
||||||
if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
|
const auto *btSession = BitTorrent::Session::instance();
|
||||||
{
|
|
||||||
if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
|
|
||||||
{
|
|
||||||
m_ui->savePath->setSelectedPath({});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const Path savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->comboCategory->currentText());
|
|
||||||
m_ui->savePath->setSelectedPath(savePath);
|
|
||||||
const Path downloadPath = BitTorrent::Session::instance()->categoryDownloadPath(m_ui->comboCategory->currentText());
|
|
||||||
m_ui->downloadPath->setSelectedPath(downloadPath);
|
|
||||||
m_ui->checkUseDownloadPath->setChecked(!downloadPath.isEmpty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
|
if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
|
||||||
{
|
{
|
||||||
|
if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
|
||||||
|
m_ui->savePath->setSelectedPath({});
|
||||||
|
|
||||||
m_ui->comboCategory->clearEditText();
|
m_ui->comboCategory->clearEditText();
|
||||||
m_ui->comboCategory->lineEdit()->setPlaceholderText(m_currentCategoriesString);
|
m_ui->comboCategory->lineEdit()->setPlaceholderText(m_currentCategoriesString);
|
||||||
|
|
||||||
|
m_ui->torrentShareLimitsWidget->setDefaults(TorrentShareLimitsWidget::UsedDefaults::Global
|
||||||
|
, BitTorrent::DEFAULT_RATIO_LIMIT, BitTorrent::DEFAULT_SEEDING_TIME_LIMIT
|
||||||
|
, BitTorrent::DEFAULT_SEEDING_TIME_LIMIT, BitTorrent::ShareLimitAction::Default);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const QString categoryName = m_ui->comboCategory->currentText();
|
||||||
|
|
||||||
|
if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
|
||||||
|
{
|
||||||
|
const Path savePath = btSession->categorySavePath(categoryName);
|
||||||
|
m_ui->savePath->setSelectedPath(savePath);
|
||||||
|
const Path downloadPath = btSession->categoryDownloadPath(categoryName);
|
||||||
|
m_ui->downloadPath->setSelectedPath(downloadPath);
|
||||||
|
m_ui->checkUseDownloadPath->setChecked(!downloadPath.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
m_ui->comboCategory->lineEdit()->setPlaceholderText(QString());
|
m_ui->comboCategory->lineEdit()->setPlaceholderText(QString());
|
||||||
|
m_ui->torrentShareLimitsWidget->setDefaults((categoryName.isEmpty() ? TorrentShareLimitsWidget::UsedDefaults::Global : TorrentShareLimitsWidget::UsedDefaults::Category)
|
||||||
|
, btSession->categoryRatioLimit(categoryName), btSession->categorySeedingTimeLimit(categoryName)
|
||||||
|
, btSession->categoryInactiveSeedingTimeLimit(categoryName), btSession->categoryShareLimitAction(categoryName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Bittorrent Client using Qt and libtorrent.
|
* Bittorrent Client using Qt and libtorrent.
|
||||||
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
|
* Copyright (C) 2024-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||||
* Copyright (C) 2020 thalieht
|
* Copyright (C) 2020 thalieht
|
||||||
* Copyright (C) 2011 Christian Kandeler
|
* Copyright (C) 2011 Christian Kandeler
|
||||||
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
#include "base/bittorrent/sharelimitaction.h"
|
#include "base/bittorrent/sharelimits.h"
|
||||||
#include "base/path.h"
|
#include "base/path.h"
|
||||||
#include "base/settingvalue.h"
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,29 @@ namespace
|
|||||||
RemoveWithContentActionIndex,
|
RemoveWithContentActionIndex,
|
||||||
SuperSeedingActionIndex
|
SuperSeedingActionIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QString shareLimitActionName(const BitTorrent::ShareLimitAction shareLimitAction)
|
||||||
|
{
|
||||||
|
switch (shareLimitAction)
|
||||||
|
{
|
||||||
|
case BitTorrent::ShareLimitAction::Stop:
|
||||||
|
return TorrentShareLimitsWidget::tr("Stop torrent");
|
||||||
|
|
||||||
|
case BitTorrent::ShareLimitAction::Remove:
|
||||||
|
return TorrentShareLimitsWidget::tr("Remove torrent");
|
||||||
|
|
||||||
|
case BitTorrent::ShareLimitAction::RemoveWithContent:
|
||||||
|
return TorrentShareLimitsWidget::tr("Remove torrent and its content");
|
||||||
|
|
||||||
|
case BitTorrent::ShareLimitAction::EnableSuperSeeding:
|
||||||
|
return TorrentShareLimitsWidget::tr("Enable super seeding for torrent");
|
||||||
|
|
||||||
|
case BitTorrent::ShareLimitAction::Default:
|
||||||
|
return TorrentShareLimitsWidget::tr("Default");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentShareLimitsWidget::TorrentShareLimitsWidget(QWidget *parent)
|
TorrentShareLimitsWidget::TorrentShareLimitsWidget(QWidget *parent)
|
||||||
@@ -60,6 +83,30 @@ TorrentShareLimitsWidget::TorrentShareLimitsWidget(QWidget *parent)
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
m_ui->comboBoxRatioMode->addItem({});
|
||||||
|
m_ui->comboBoxRatioMode->addItem(tr("Unlimited"));
|
||||||
|
m_ui->comboBoxRatioMode->addItem(tr("Set to"));
|
||||||
|
m_ui->comboBoxRatioMode->setCurrentIndex(UninitializedModeIndex);
|
||||||
|
|
||||||
|
m_ui->comboBoxSeedingTimeMode->addItem({});
|
||||||
|
m_ui->comboBoxSeedingTimeMode->addItem(tr("Unlimited"));
|
||||||
|
m_ui->comboBoxSeedingTimeMode->addItem(tr("Set to"));
|
||||||
|
m_ui->comboBoxSeedingTimeMode->setCurrentIndex(UninitializedModeIndex);
|
||||||
|
|
||||||
|
m_ui->comboBoxInactiveSeedingTimeMode->addItem({});
|
||||||
|
m_ui->comboBoxInactiveSeedingTimeMode->addItem(tr("Unlimited"));
|
||||||
|
m_ui->comboBoxInactiveSeedingTimeMode->addItem(tr("Set to"));
|
||||||
|
m_ui->comboBoxInactiveSeedingTimeMode->setCurrentIndex(UninitializedModeIndex);
|
||||||
|
|
||||||
|
m_ui->comboBoxAction->addItem({});
|
||||||
|
m_ui->comboBoxAction->addItem(shareLimitActionName(BitTorrent::ShareLimitAction::Stop));
|
||||||
|
m_ui->comboBoxAction->addItem(shareLimitActionName(BitTorrent::ShareLimitAction::Remove));
|
||||||
|
m_ui->comboBoxAction->addItem(shareLimitActionName(BitTorrent::ShareLimitAction::RemoveWithContent));
|
||||||
|
m_ui->comboBoxAction->addItem(shareLimitActionName(BitTorrent::ShareLimitAction::EnableSuperSeeding));
|
||||||
|
m_ui->comboBoxAction->setCurrentIndex(UninitializedActionIndex);
|
||||||
|
|
||||||
|
resetDefaultItemsText();
|
||||||
|
|
||||||
m_ui->spinBoxRatioValue->setEnabled(false);
|
m_ui->spinBoxRatioValue->setEnabled(false);
|
||||||
m_ui->spinBoxRatioValue->setMaximum(std::numeric_limits<int>::max());
|
m_ui->spinBoxRatioValue->setMaximum(std::numeric_limits<int>::max());
|
||||||
m_ui->spinBoxRatioValue->setSuffix({});
|
m_ui->spinBoxRatioValue->setSuffix({});
|
||||||
@@ -71,9 +118,25 @@ TorrentShareLimitsWidget::TorrentShareLimitsWidget(QWidget *parent)
|
|||||||
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix({});
|
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix({});
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->clear();
|
m_ui->spinBoxInactiveSeedingTimeValue->clear();
|
||||||
|
|
||||||
connect(m_ui->comboBoxRatioMode, &QComboBox::currentIndexChanged, this, &TorrentShareLimitsWidget::refreshRatioLimitControls);
|
int prevIndex = UninitializedModeIndex;
|
||||||
connect(m_ui->comboBoxSeedingTimeMode, &QComboBox::currentIndexChanged, this, &TorrentShareLimitsWidget::refreshSeedingTimeLimitControls);
|
connect(m_ui->comboBoxRatioMode, &QComboBox::currentIndexChanged, this
|
||||||
connect(m_ui->comboBoxInactiveSeedingTimeMode, &QComboBox::currentIndexChanged, this, &TorrentShareLimitsWidget::refreshInactiveSeedingTimeLimitControls);
|
, [this, prevIndex](const int currentIndex) mutable
|
||||||
|
{
|
||||||
|
onRatioLimitModeChanged(currentIndex, prevIndex);
|
||||||
|
prevIndex = currentIndex;
|
||||||
|
});
|
||||||
|
connect(m_ui->comboBoxSeedingTimeMode, &QComboBox::currentIndexChanged, this
|
||||||
|
, [this, prevIndex](const int currentIndex) mutable
|
||||||
|
{
|
||||||
|
onSeedingTimeLimitModeChanged(currentIndex, prevIndex);
|
||||||
|
prevIndex = currentIndex;
|
||||||
|
});
|
||||||
|
connect(m_ui->comboBoxInactiveSeedingTimeMode, &QComboBox::currentIndexChanged, this
|
||||||
|
, [this, prevIndex](const int currentIndex) mutable
|
||||||
|
{
|
||||||
|
onInactiveSeedingTimeLimitModeChanged(currentIndex, prevIndex);
|
||||||
|
prevIndex = currentIndex;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TorrentShareLimitsWidget::~TorrentShareLimitsWidget()
|
TorrentShareLimitsWidget::~TorrentShareLimitsWidget()
|
||||||
@@ -83,11 +146,11 @@ TorrentShareLimitsWidget::~TorrentShareLimitsWidget()
|
|||||||
|
|
||||||
void TorrentShareLimitsWidget::setRatioLimit(const qreal ratioLimit)
|
void TorrentShareLimitsWidget::setRatioLimit(const qreal ratioLimit)
|
||||||
{
|
{
|
||||||
if (ratioLimit == BitTorrent::Torrent::USE_GLOBAL_RATIO)
|
if (ratioLimit == BitTorrent::DEFAULT_RATIO_LIMIT)
|
||||||
{
|
{
|
||||||
m_ui->comboBoxRatioMode->setCurrentIndex(DefaultModeIndex);
|
m_ui->comboBoxRatioMode->setCurrentIndex(DefaultModeIndex);
|
||||||
}
|
}
|
||||||
else if (ratioLimit == BitTorrent::Torrent::NO_RATIO_LIMIT)
|
else if (ratioLimit == BitTorrent::NO_RATIO_LIMIT)
|
||||||
{
|
{
|
||||||
m_ui->comboBoxRatioMode->setCurrentIndex(UnlimitedModeIndex);
|
m_ui->comboBoxRatioMode->setCurrentIndex(UnlimitedModeIndex);
|
||||||
}
|
}
|
||||||
@@ -100,11 +163,11 @@ void TorrentShareLimitsWidget::setRatioLimit(const qreal ratioLimit)
|
|||||||
|
|
||||||
void TorrentShareLimitsWidget::setSeedingTimeLimit(const int seedingTimeLimit)
|
void TorrentShareLimitsWidget::setSeedingTimeLimit(const int seedingTimeLimit)
|
||||||
{
|
{
|
||||||
if (seedingTimeLimit == BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME)
|
if (seedingTimeLimit == BitTorrent::DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
{
|
{
|
||||||
m_ui->comboBoxSeedingTimeMode->setCurrentIndex(DefaultModeIndex);
|
m_ui->comboBoxSeedingTimeMode->setCurrentIndex(DefaultModeIndex);
|
||||||
}
|
}
|
||||||
else if (seedingTimeLimit == BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT)
|
else if (seedingTimeLimit == BitTorrent::NO_SEEDING_TIME_LIMIT)
|
||||||
{
|
{
|
||||||
m_ui->comboBoxSeedingTimeMode->setCurrentIndex(UnlimitedModeIndex);
|
m_ui->comboBoxSeedingTimeMode->setCurrentIndex(UnlimitedModeIndex);
|
||||||
}
|
}
|
||||||
@@ -117,11 +180,11 @@ void TorrentShareLimitsWidget::setSeedingTimeLimit(const int seedingTimeLimit)
|
|||||||
|
|
||||||
void TorrentShareLimitsWidget::setInactiveSeedingTimeLimit(const int inactiveSeedingTimeLimit)
|
void TorrentShareLimitsWidget::setInactiveSeedingTimeLimit(const int inactiveSeedingTimeLimit)
|
||||||
{
|
{
|
||||||
if (inactiveSeedingTimeLimit == BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME)
|
if (inactiveSeedingTimeLimit == BitTorrent::DEFAULT_SEEDING_TIME_LIMIT)
|
||||||
{
|
{
|
||||||
m_ui->comboBoxInactiveSeedingTimeMode->setCurrentIndex(DefaultModeIndex);
|
m_ui->comboBoxInactiveSeedingTimeMode->setCurrentIndex(DefaultModeIndex);
|
||||||
}
|
}
|
||||||
else if (inactiveSeedingTimeLimit == BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT)
|
else if (inactiveSeedingTimeLimit == BitTorrent::NO_SEEDING_TIME_LIMIT)
|
||||||
{
|
{
|
||||||
m_ui->comboBoxInactiveSeedingTimeMode->setCurrentIndex(UnlimitedModeIndex);
|
m_ui->comboBoxInactiveSeedingTimeMode->setCurrentIndex(UnlimitedModeIndex);
|
||||||
}
|
}
|
||||||
@@ -155,25 +218,56 @@ void TorrentShareLimitsWidget::setShareLimitAction(const BitTorrent::ShareLimitA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentShareLimitsWidget::setDefaultLimits(const qreal ratioLimit, const int seedingTimeLimit, const int inactiveSeedingTimeLimit)
|
void TorrentShareLimitsWidget::setDefaults(UsedDefaults usedDefaults
|
||||||
|
, const qreal ratioLimit, const int seedingTimeLimit
|
||||||
|
, const int inactiveSeedingTimeLimit, const BitTorrent::ShareLimitAction action)
|
||||||
{
|
{
|
||||||
if (m_defaultRatioLimit != ratioLimit)
|
|
||||||
{
|
|
||||||
m_defaultRatioLimit = ratioLimit;
|
m_defaultRatioLimit = ratioLimit;
|
||||||
refreshRatioLimitControls();
|
if (m_ui->comboBoxRatioMode->currentIndex() == DefaultModeIndex)
|
||||||
|
{
|
||||||
|
if (m_defaultRatioLimit >= 0)
|
||||||
|
{
|
||||||
|
m_ui->spinBoxRatioValue->setValue(m_defaultRatioLimit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui->spinBoxRatioValue->clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_defaultSeedingTimeLimit != seedingTimeLimit)
|
|
||||||
{
|
|
||||||
m_defaultSeedingTimeLimit = seedingTimeLimit;
|
m_defaultSeedingTimeLimit = seedingTimeLimit;
|
||||||
refreshSeedingTimeLimitControls();
|
if (m_ui->comboBoxSeedingTimeMode->currentIndex() == DefaultModeIndex)
|
||||||
|
{
|
||||||
|
if (m_defaultSeedingTimeLimit >= 0)
|
||||||
|
{
|
||||||
|
m_ui->spinBoxSeedingTimeValue->setValue(m_defaultSeedingTimeLimit);
|
||||||
|
m_ui->spinBoxSeedingTimeValue->setSuffix(tr(" min"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui->spinBoxSeedingTimeValue->setSuffix({});
|
||||||
|
m_ui->spinBoxSeedingTimeValue->clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_defaultInactiveSeedingTimeLimit != inactiveSeedingTimeLimit)
|
|
||||||
{
|
|
||||||
m_defaultInactiveSeedingTimeLimit = inactiveSeedingTimeLimit;
|
m_defaultInactiveSeedingTimeLimit = inactiveSeedingTimeLimit;
|
||||||
refreshInactiveSeedingTimeLimitControls();
|
if (m_ui->comboBoxInactiveSeedingTimeMode->currentIndex() == DefaultModeIndex)
|
||||||
|
{
|
||||||
|
if (m_defaultInactiveSeedingTimeLimit >= 0)
|
||||||
|
{
|
||||||
|
m_ui->spinBoxInactiveSeedingTimeValue->setValue(m_defaultInactiveSeedingTimeLimit);
|
||||||
|
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix(tr(" min"));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix({});
|
||||||
|
m_ui->spinBoxInactiveSeedingTimeValue->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_defaultShareLimitAction = action;
|
||||||
|
m_usedDefaults = usedDefaults;
|
||||||
|
resetDefaultItemsText();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<qreal> TorrentShareLimitsWidget::ratioLimit() const
|
std::optional<qreal> TorrentShareLimitsWidget::ratioLimit() const
|
||||||
@@ -181,9 +275,9 @@ std::optional<qreal> TorrentShareLimitsWidget::ratioLimit() const
|
|||||||
switch (m_ui->comboBoxRatioMode->currentIndex())
|
switch (m_ui->comboBoxRatioMode->currentIndex())
|
||||||
{
|
{
|
||||||
case DefaultModeIndex:
|
case DefaultModeIndex:
|
||||||
return BitTorrent::Torrent::USE_GLOBAL_RATIO;
|
return BitTorrent::DEFAULT_RATIO_LIMIT;
|
||||||
case UnlimitedModeIndex:
|
case UnlimitedModeIndex:
|
||||||
return BitTorrent::Torrent::NO_RATIO_LIMIT;
|
return BitTorrent::NO_RATIO_LIMIT;
|
||||||
case AssignedModeIndex:
|
case AssignedModeIndex:
|
||||||
return m_ui->spinBoxRatioValue->value();
|
return m_ui->spinBoxRatioValue->value();
|
||||||
default:
|
default:
|
||||||
@@ -196,9 +290,9 @@ std::optional<int> TorrentShareLimitsWidget::seedingTimeLimit() const
|
|||||||
switch (m_ui->comboBoxSeedingTimeMode->currentIndex())
|
switch (m_ui->comboBoxSeedingTimeMode->currentIndex())
|
||||||
{
|
{
|
||||||
case DefaultModeIndex:
|
case DefaultModeIndex:
|
||||||
return BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME;
|
return BitTorrent::DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
case UnlimitedModeIndex:
|
case UnlimitedModeIndex:
|
||||||
return BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT;
|
return BitTorrent::NO_SEEDING_TIME_LIMIT;
|
||||||
case AssignedModeIndex:
|
case AssignedModeIndex:
|
||||||
return m_ui->spinBoxSeedingTimeValue->value();
|
return m_ui->spinBoxSeedingTimeValue->value();
|
||||||
default:
|
default:
|
||||||
@@ -211,9 +305,9 @@ std::optional<int> TorrentShareLimitsWidget::inactiveSeedingTimeLimit() const
|
|||||||
switch (m_ui->comboBoxInactiveSeedingTimeMode->currentIndex())
|
switch (m_ui->comboBoxInactiveSeedingTimeMode->currentIndex())
|
||||||
{
|
{
|
||||||
case DefaultModeIndex:
|
case DefaultModeIndex:
|
||||||
return BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
return BitTorrent::DEFAULT_SEEDING_TIME_LIMIT;
|
||||||
case UnlimitedModeIndex:
|
case UnlimitedModeIndex:
|
||||||
return BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT;
|
return BitTorrent::NO_SEEDING_TIME_LIMIT;
|
||||||
case AssignedModeIndex:
|
case AssignedModeIndex:
|
||||||
return m_ui->spinBoxInactiveSeedingTimeValue->value();
|
return m_ui->spinBoxInactiveSeedingTimeValue->value();
|
||||||
default:
|
default:
|
||||||
@@ -240,68 +334,97 @@ std::optional<BitTorrent::ShareLimitAction> TorrentShareLimitsWidget::shareLimit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentShareLimitsWidget::refreshRatioLimitControls()
|
void TorrentShareLimitsWidget::onRatioLimitModeChanged(const int currentIndex, const int previousIndex)
|
||||||
{
|
{
|
||||||
const auto index = m_ui->comboBoxRatioMode->currentIndex();
|
m_ui->spinBoxRatioValue->setEnabled(currentIndex == AssignedModeIndex);
|
||||||
|
|
||||||
m_ui->spinBoxRatioValue->setEnabled(index == AssignedModeIndex);
|
if (previousIndex == AssignedModeIndex)
|
||||||
if (index == AssignedModeIndex)
|
m_ratioLimit = m_ui->spinBoxRatioValue->value();
|
||||||
|
|
||||||
|
if (currentIndex == AssignedModeIndex)
|
||||||
{
|
{
|
||||||
m_ui->spinBoxRatioValue->setValue(m_ratioLimit);
|
m_ui->spinBoxRatioValue->setValue(m_ratioLimit);
|
||||||
}
|
}
|
||||||
else if ((index == DefaultModeIndex) && (m_defaultRatioLimit >= 0))
|
else if ((currentIndex == DefaultModeIndex) && (m_defaultRatioLimit >= 0))
|
||||||
{
|
{
|
||||||
m_ui->spinBoxRatioValue->setValue(m_defaultRatioLimit);
|
m_ui->spinBoxRatioValue->setValue(m_defaultRatioLimit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_ratioLimit = m_ui->spinBoxRatioValue->value();
|
|
||||||
m_ui->spinBoxRatioValue->clear();
|
m_ui->spinBoxRatioValue->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentShareLimitsWidget::refreshSeedingTimeLimitControls()
|
void TorrentShareLimitsWidget::onSeedingTimeLimitModeChanged(const int currentIndex, const int previousIndex)
|
||||||
{
|
{
|
||||||
const auto index = m_ui->comboBoxSeedingTimeMode->currentIndex();
|
m_ui->spinBoxSeedingTimeValue->setEnabled(currentIndex == AssignedModeIndex);
|
||||||
|
|
||||||
m_ui->spinBoxSeedingTimeValue->setEnabled(index == AssignedModeIndex);
|
if (previousIndex == AssignedModeIndex)
|
||||||
if (index == AssignedModeIndex)
|
m_seedingTimeLimit = m_ui->spinBoxSeedingTimeValue->value();
|
||||||
|
|
||||||
|
if (currentIndex == AssignedModeIndex)
|
||||||
{
|
{
|
||||||
m_ui->spinBoxSeedingTimeValue->setValue(m_seedingTimeLimit);
|
m_ui->spinBoxSeedingTimeValue->setValue(m_seedingTimeLimit);
|
||||||
m_ui->spinBoxSeedingTimeValue->setSuffix(tr(" min"));
|
m_ui->spinBoxSeedingTimeValue->setSuffix(tr(" min"));
|
||||||
}
|
}
|
||||||
else if ((index == DefaultModeIndex) && (m_defaultSeedingTimeLimit >= 0))
|
else if ((currentIndex == DefaultModeIndex) && (m_defaultSeedingTimeLimit >= 0))
|
||||||
{
|
{
|
||||||
m_ui->spinBoxSeedingTimeValue->setValue(m_defaultSeedingTimeLimit);
|
m_ui->spinBoxSeedingTimeValue->setValue(m_defaultSeedingTimeLimit);
|
||||||
m_ui->spinBoxSeedingTimeValue->setSuffix(tr(" min"));
|
m_ui->spinBoxSeedingTimeValue->setSuffix(tr(" min"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_seedingTimeLimit = m_ui->spinBoxSeedingTimeValue->value();
|
|
||||||
m_ui->spinBoxSeedingTimeValue->setSuffix({});
|
m_ui->spinBoxSeedingTimeValue->setSuffix({});
|
||||||
m_ui->spinBoxSeedingTimeValue->clear();
|
m_ui->spinBoxSeedingTimeValue->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentShareLimitsWidget::refreshInactiveSeedingTimeLimitControls()
|
void TorrentShareLimitsWidget::onInactiveSeedingTimeLimitModeChanged(const int currentIndex, const int previousIndex)
|
||||||
{
|
{
|
||||||
const auto index = m_ui->comboBoxInactiveSeedingTimeMode->currentIndex();
|
m_ui->spinBoxInactiveSeedingTimeValue->setEnabled(currentIndex == AssignedModeIndex);
|
||||||
|
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->setEnabled(index == AssignedModeIndex);
|
if (previousIndex == AssignedModeIndex)
|
||||||
if (index == AssignedModeIndex)
|
m_inactiveSeedingTimeLimit = m_ui->spinBoxInactiveSeedingTimeValue->value();
|
||||||
|
|
||||||
|
if (currentIndex == AssignedModeIndex)
|
||||||
{
|
{
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->setValue(m_inactiveSeedingTimeLimit);
|
m_ui->spinBoxInactiveSeedingTimeValue->setValue(m_inactiveSeedingTimeLimit);
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix(tr(" min"));
|
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix(tr(" min"));
|
||||||
}
|
}
|
||||||
else if ((index == DefaultModeIndex) && (m_defaultInactiveSeedingTimeLimit >= 0))
|
else if ((currentIndex == DefaultModeIndex) && (m_defaultInactiveSeedingTimeLimit >= 0))
|
||||||
{
|
{
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->setValue(m_defaultInactiveSeedingTimeLimit);
|
m_ui->spinBoxInactiveSeedingTimeValue->setValue(m_defaultInactiveSeedingTimeLimit);
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix(tr(" min"));
|
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix(tr(" min"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_inactiveSeedingTimeLimit = m_ui->spinBoxInactiveSeedingTimeValue->value();
|
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix({});
|
m_ui->spinBoxInactiveSeedingTimeValue->setSuffix({});
|
||||||
m_ui->spinBoxInactiveSeedingTimeValue->clear();
|
m_ui->spinBoxInactiveSeedingTimeValue->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentShareLimitsWidget::resetDefaultItemsText()
|
||||||
|
{
|
||||||
|
if (m_usedDefaults == UsedDefaults::Global)
|
||||||
|
{
|
||||||
|
m_ui->comboBoxRatioMode->setItemText(DefaultModeIndex, tr("Default"));
|
||||||
|
m_ui->comboBoxSeedingTimeMode->setItemText(DefaultModeIndex, tr("Default"));
|
||||||
|
m_ui->comboBoxInactiveSeedingTimeMode->setItemText(DefaultModeIndex, tr("Default"));
|
||||||
|
|
||||||
|
m_ui->comboBoxAction->setItemText(DefaultActionIndex
|
||||||
|
, (m_defaultShareLimitAction == BitTorrent::ShareLimitAction::Default)
|
||||||
|
? tr("Default")
|
||||||
|
: tr("Default (%1)", "Default (share limit action)").arg(shareLimitActionName(m_defaultShareLimitAction)));
|
||||||
|
}
|
||||||
|
else // TorrentOptions
|
||||||
|
{
|
||||||
|
m_ui->comboBoxRatioMode->setItemText(DefaultModeIndex, tr("From category"));
|
||||||
|
m_ui->comboBoxSeedingTimeMode->setItemText(DefaultModeIndex, tr("From category"));
|
||||||
|
m_ui->comboBoxInactiveSeedingTimeMode->setItemText(DefaultModeIndex, tr("From category"));
|
||||||
|
|
||||||
|
m_ui->comboBoxAction->setItemText(DefaultActionIndex
|
||||||
|
, (m_defaultShareLimitAction == BitTorrent::ShareLimitAction::Default)
|
||||||
|
? tr("From category")
|
||||||
|
: tr("From category (%1)", "From category (share limit action)").arg(shareLimitActionName(m_defaultShareLimitAction)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
#include "base/bittorrent/sharelimitaction.h"
|
#include "base/bittorrent/sharelimits.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
@@ -45,6 +45,12 @@ class TorrentShareLimitsWidget final : public QWidget
|
|||||||
Q_DISABLE_COPY_MOVE(TorrentShareLimitsWidget)
|
Q_DISABLE_COPY_MOVE(TorrentShareLimitsWidget)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class UsedDefaults
|
||||||
|
{
|
||||||
|
Global,
|
||||||
|
Category
|
||||||
|
};
|
||||||
|
|
||||||
explicit TorrentShareLimitsWidget(QWidget *parent = nullptr);
|
explicit TorrentShareLimitsWidget(QWidget *parent = nullptr);
|
||||||
~TorrentShareLimitsWidget() override;
|
~TorrentShareLimitsWidget() override;
|
||||||
|
|
||||||
@@ -53,7 +59,8 @@ public:
|
|||||||
void setInactiveSeedingTimeLimit(int inactiveSeedingTimeLimit);
|
void setInactiveSeedingTimeLimit(int inactiveSeedingTimeLimit);
|
||||||
void setShareLimitAction(BitTorrent::ShareLimitAction action);
|
void setShareLimitAction(BitTorrent::ShareLimitAction action);
|
||||||
|
|
||||||
void setDefaultLimits(qreal ratioLimit, int seedingTimeLimit, int inactiveSeedingTimeLimit);
|
void setDefaults(UsedDefaults usedDefaults, qreal ratioLimit, int seedingTimeLimit
|
||||||
|
, int inactiveSeedingTimeLimit, BitTorrent::ShareLimitAction action);
|
||||||
|
|
||||||
std::optional<qreal> ratioLimit() const;
|
std::optional<qreal> ratioLimit() const;
|
||||||
std::optional<int> seedingTimeLimit() const;
|
std::optional<int> seedingTimeLimit() const;
|
||||||
@@ -61,9 +68,10 @@ public:
|
|||||||
std::optional<BitTorrent::ShareLimitAction> shareLimitAction() const;
|
std::optional<BitTorrent::ShareLimitAction> shareLimitAction() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshRatioLimitControls();
|
void onRatioLimitModeChanged(int currentIndex, int previousIndex);
|
||||||
void refreshSeedingTimeLimitControls();
|
void onSeedingTimeLimitModeChanged(int currentIndex, int previousIndex);
|
||||||
void refreshInactiveSeedingTimeLimitControls();
|
void onInactiveSeedingTimeLimitModeChanged(int currentIndex, int previousIndex);
|
||||||
|
void resetDefaultItemsText();
|
||||||
|
|
||||||
Ui::TorrentShareLimitsWidget *m_ui = nullptr;
|
Ui::TorrentShareLimitsWidget *m_ui = nullptr;
|
||||||
|
|
||||||
@@ -74,4 +82,7 @@ private:
|
|||||||
int m_defaultSeedingTimeLimit = -1;
|
int m_defaultSeedingTimeLimit = -1;
|
||||||
int m_defaultInactiveSeedingTimeLimit = -1;
|
int m_defaultInactiveSeedingTimeLimit = -1;
|
||||||
qreal m_defaultRatioLimit = -1;
|
qreal m_defaultRatioLimit = -1;
|
||||||
|
BitTorrent::ShareLimitAction m_defaultShareLimitAction = BitTorrent::ShareLimitAction::Default;
|
||||||
|
|
||||||
|
UsedDefaults m_usedDefaults = UsedDefaults::Global;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,26 +21,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QComboBox" name="comboBoxRatioMode">
|
<widget class="QComboBox" name="comboBoxRatioMode"/>
|
||||||
<property name="currentIndex">
|
|
||||||
<number>-1</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Unlimited</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set to</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2">
|
<item row="0" column="2">
|
||||||
<widget class="QDoubleSpinBox" name="spinBoxRatioValue">
|
<widget class="QDoubleSpinBox" name="spinBoxRatioValue">
|
||||||
@@ -63,26 +44,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QComboBox" name="comboBoxSeedingTimeMode">
|
<widget class="QComboBox" name="comboBoxSeedingTimeMode"/>
|
||||||
<property name="currentIndex">
|
|
||||||
<number>-1</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Unlimited</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set to</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="QSpinBox" name="spinBoxSeedingTimeValue">
|
<widget class="QSpinBox" name="spinBoxSeedingTimeValue">
|
||||||
@@ -108,26 +70,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QComboBox" name="comboBoxInactiveSeedingTimeMode">
|
<widget class="QComboBox" name="comboBoxInactiveSeedingTimeMode"/>
|
||||||
<property name="currentIndex">
|
|
||||||
<number>-1</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Unlimited</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Set to</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2">
|
<item row="2" column="2">
|
||||||
<widget class="QSpinBox" name="spinBoxInactiveSeedingTimeValue">
|
<widget class="QSpinBox" name="spinBoxInactiveSeedingTimeValue">
|
||||||
@@ -157,36 +100,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="comboBoxAction">
|
<widget class="QComboBox" name="comboBoxAction"/>
|
||||||
<property name="currentIndex">
|
|
||||||
<number>-1</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Default</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Stop torrent</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Remove torrent</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Remove torrent and its content</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Enable super seeding for torrent</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="actionLayoutSpacer">
|
<spacer name="actionLayoutSpacer">
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ QString TransferListModel::displayValue(const BitTorrent::Torrent *torrent, cons
|
|||||||
case TR_RATIO:
|
case TR_RATIO:
|
||||||
return ratioString(torrent->realRatio());
|
return ratioString(torrent->realRatio());
|
||||||
case TR_RATIO_LIMIT:
|
case TR_RATIO_LIMIT:
|
||||||
return ratioString(torrent->maxRatio());
|
return ratioString(torrent->effectiveRatioLimit());
|
||||||
case TR_POPULARITY:
|
case TR_POPULARITY:
|
||||||
return ratioString(torrent->popularity());
|
return ratioString(torrent->popularity());
|
||||||
case TR_CATEGORY:
|
case TR_CATEGORY:
|
||||||
@@ -509,7 +509,7 @@ QVariant TransferListModel::internalValue(const BitTorrent::Torrent *torrent, co
|
|||||||
case TR_COMPLETED:
|
case TR_COMPLETED:
|
||||||
return torrent->completedSize();
|
return torrent->completedSize();
|
||||||
case TR_RATIO_LIMIT:
|
case TR_RATIO_LIMIT:
|
||||||
return torrent->maxRatio();
|
return torrent->effectiveRatioLimit();
|
||||||
case TR_SEEN_COMPLETE_DATE:
|
case TR_SEEN_COMPLETE_DATE:
|
||||||
return torrent->lastSeenComplete();
|
return torrent->lastSeenComplete();
|
||||||
case TR_LAST_ACTIVITY:
|
case TR_LAST_ACTIVITY:
|
||||||
|
|||||||
@@ -163,9 +163,9 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
|
|||||||
{KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()},
|
{KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()},
|
||||||
{KEY_TORRENT_CONNECTIONS_COUNT, torrent.connectionsCount()},
|
{KEY_TORRENT_CONNECTIONS_COUNT, torrent.connectionsCount()},
|
||||||
{KEY_TORRENT_CONNECTIONS_LIMIT, torrent.connectionsLimit()},
|
{KEY_TORRENT_CONNECTIONS_LIMIT, torrent.connectionsLimit()},
|
||||||
{KEY_TORRENT_MAX_RATIO, torrent.maxRatio()},
|
{KEY_TORRENT_MAX_RATIO, torrent.effectiveRatioLimit()},
|
||||||
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()},
|
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.effectiveSeedingTimeLimit()},
|
||||||
{KEY_TORRENT_MAX_INACTIVE_SEEDING_TIME, torrent.maxInactiveSeedingTime()},
|
{KEY_TORRENT_MAX_INACTIVE_SEEDING_TIME, torrent.effectiveInactiveSeedingTimeLimit()},
|
||||||
{KEY_TORRENT_RATIO, adjustRatio(torrent.realRatio())},
|
{KEY_TORRENT_RATIO, adjustRatio(torrent.realRatio())},
|
||||||
{KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()},
|
{KEY_TORRENT_RATIO_LIMIT, torrent.ratioLimit()},
|
||||||
{KEY_TORRENT_POPULARITY, torrent.popularity()},
|
{KEY_TORRENT_POPULARITY, torrent.popularity()},
|
||||||
|
|||||||
@@ -1066,9 +1066,9 @@ void TorrentsController::addAction()
|
|||||||
const QString torrentName = params()[u"rename"_s].trimmed();
|
const QString torrentName = params()[u"rename"_s].trimmed();
|
||||||
const int upLimit = parseInt(params()[u"upLimit"_s]).value_or(-1);
|
const int upLimit = parseInt(params()[u"upLimit"_s]).value_or(-1);
|
||||||
const int dlLimit = parseInt(params()[u"dlLimit"_s]).value_or(-1);
|
const int dlLimit = parseInt(params()[u"dlLimit"_s]).value_or(-1);
|
||||||
const double ratioLimit = parseDouble(params()[u"ratioLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_RATIO);
|
const double ratioLimit = parseDouble(params()[u"ratioLimit"_s]).value_or(BitTorrent::DEFAULT_RATIO_LIMIT);
|
||||||
const int seedingTimeLimit = parseInt(params()[u"seedingTimeLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
|
const int seedingTimeLimit = parseInt(params()[u"seedingTimeLimit"_s]).value_or(BitTorrent::DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
const int inactiveSeedingTimeLimit = parseInt(params()[u"inactiveSeedingTimeLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
const int inactiveSeedingTimeLimit = parseInt(params()[u"inactiveSeedingTimeLimit"_s]).value_or(BitTorrent::DEFAULT_SEEDING_TIME_LIMIT);
|
||||||
const BitTorrent::ShareLimitAction shareLimitAction = Utils::String::toEnum(params()[u"shareLimitAction"_s], BitTorrent::ShareLimitAction::Default);
|
const BitTorrent::ShareLimitAction shareLimitAction = Utils::String::toEnum(params()[u"shareLimitAction"_s], BitTorrent::ShareLimitAction::Default);
|
||||||
const std::optional<bool> autoTMM = parseBool(params()[u"autoTMM"_s]);
|
const std::optional<bool> autoTMM = parseBool(params()[u"autoTMM"_s]);
|
||||||
|
|
||||||
@@ -1897,7 +1897,7 @@ void TorrentsController::editCategoryAction()
|
|||||||
categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
|
categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BitTorrent::Session::instance()->editCategory(category, categoryOptions))
|
if (!BitTorrent::Session::instance()->setCategoryOptions(category, categoryOptions))
|
||||||
throw APIError(APIErrorType::Conflict, tr("Unable to edit category"));
|
throw APIError(APIErrorType::Conflict, tr("Unable to edit category"));
|
||||||
|
|
||||||
setResult(QString());
|
setResult(QString());
|
||||||
|
|||||||
Reference in New Issue
Block a user