mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-25 05:54:33 +00:00
Add option to stop seeding when torrent has been inactive
PR #19294. Closes #533. Closes #8073. Closes #15939.
This commit is contained in:
parent
f99a98306d
commit
35e18498d9
@ -50,6 +50,7 @@ const QString PARAM_AUTOTMM = u"use_auto_tmm"_s;
|
|||||||
const QString PARAM_UPLOADLIMIT = u"upload_limit"_s;
|
const QString PARAM_UPLOADLIMIT = u"upload_limit"_s;
|
||||||
const QString PARAM_DOWNLOADLIMIT = u"download_limit"_s;
|
const QString PARAM_DOWNLOADLIMIT = u"download_limit"_s;
|
||||||
const QString PARAM_SEEDINGTIMELIMIT = u"seeding_time_limit"_s;
|
const QString PARAM_SEEDINGTIMELIMIT = u"seeding_time_limit"_s;
|
||||||
|
const QString PARAM_INACTIVESEEDINGTIMELIMIT = u"inactive_seeding_time_limit"_s;
|
||||||
const QString PARAM_RATIOLIMIT = u"ratio_limit"_s;
|
const QString PARAM_RATIOLIMIT = u"ratio_limit"_s;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -107,14 +108,14 @@ bool BitTorrent::operator==(const AddTorrentParams &lhs, const AddTorrentParams
|
|||||||
lhs.addToQueueTop, lhs.addPaused, lhs.stopCondition,
|
lhs.addToQueueTop, lhs.addPaused, lhs.stopCondition,
|
||||||
lhs.filePaths, lhs.filePriorities, lhs.skipChecking,
|
lhs.filePaths, lhs.filePriorities, lhs.skipChecking,
|
||||||
lhs.contentLayout, lhs.useAutoTMM, lhs.uploadLimit,
|
lhs.contentLayout, lhs.useAutoTMM, lhs.uploadLimit,
|
||||||
lhs.downloadLimit, lhs.seedingTimeLimit, lhs.ratioLimit)
|
lhs.downloadLimit, lhs.seedingTimeLimit, lhs.inactiveSeedingTimeLimit, lhs.ratioLimit)
|
||||||
== std::tie(rhs.name, rhs.category, rhs.tags,
|
== std::tie(rhs.name, rhs.category, rhs.tags,
|
||||||
rhs.savePath, rhs.useDownloadPath, rhs.downloadPath,
|
rhs.savePath, rhs.useDownloadPath, rhs.downloadPath,
|
||||||
rhs.sequential, rhs.firstLastPiecePriority, rhs.addForced,
|
rhs.sequential, rhs.firstLastPiecePriority, rhs.addForced,
|
||||||
rhs.addToQueueTop, rhs.addPaused, rhs.stopCondition,
|
rhs.addToQueueTop, rhs.addPaused, rhs.stopCondition,
|
||||||
rhs.filePaths, rhs.filePriorities, rhs.skipChecking,
|
rhs.filePaths, rhs.filePriorities, rhs.skipChecking,
|
||||||
rhs.contentLayout, rhs.useAutoTMM, rhs.uploadLimit,
|
rhs.contentLayout, rhs.useAutoTMM, rhs.uploadLimit,
|
||||||
rhs.downloadLimit, rhs.seedingTimeLimit, rhs.ratioLimit);
|
rhs.downloadLimit, rhs.seedingTimeLimit, rhs.inactiveSeedingTimeLimit, rhs.ratioLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
BitTorrent::AddTorrentParams BitTorrent::parseAddTorrentParams(const QJsonObject &jsonObj)
|
BitTorrent::AddTorrentParams BitTorrent::parseAddTorrentParams(const QJsonObject &jsonObj)
|
||||||
@ -134,6 +135,7 @@ BitTorrent::AddTorrentParams BitTorrent::parseAddTorrentParams(const QJsonObject
|
|||||||
params.uploadLimit = jsonObj.value(PARAM_UPLOADLIMIT).toInt(-1);
|
params.uploadLimit = jsonObj.value(PARAM_UPLOADLIMIT).toInt(-1);
|
||||||
params.downloadLimit = jsonObj.value(PARAM_DOWNLOADLIMIT).toInt(-1);
|
params.downloadLimit = jsonObj.value(PARAM_DOWNLOADLIMIT).toInt(-1);
|
||||||
params.seedingTimeLimit = jsonObj.value(PARAM_SEEDINGTIMELIMIT).toInt(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
|
params.seedingTimeLimit = jsonObj.value(PARAM_SEEDINGTIMELIMIT).toInt(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||||
|
params.inactiveSeedingTimeLimit = jsonObj.value(PARAM_INACTIVESEEDINGTIMELIMIT).toInt(BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
||||||
params.ratioLimit = jsonObj.value(PARAM_RATIOLIMIT).toDouble(BitTorrent::Torrent::USE_GLOBAL_RATIO);
|
params.ratioLimit = jsonObj.value(PARAM_RATIOLIMIT).toDouble(BitTorrent::Torrent::USE_GLOBAL_RATIO);
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
@ -152,6 +154,7 @@ QJsonObject BitTorrent::serializeAddTorrentParams(const AddTorrentParams ¶ms
|
|||||||
{PARAM_UPLOADLIMIT, params.uploadLimit},
|
{PARAM_UPLOADLIMIT, params.uploadLimit},
|
||||||
{PARAM_DOWNLOADLIMIT, params.downloadLimit},
|
{PARAM_DOWNLOADLIMIT, params.downloadLimit},
|
||||||
{PARAM_SEEDINGTIMELIMIT, params.seedingTimeLimit},
|
{PARAM_SEEDINGTIMELIMIT, params.seedingTimeLimit},
|
||||||
|
{PARAM_INACTIVESEEDINGTIMELIMIT, params.inactiveSeedingTimeLimit},
|
||||||
{PARAM_RATIOLIMIT, params.ratioLimit}
|
{PARAM_RATIOLIMIT, params.ratioLimit}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ namespace BitTorrent
|
|||||||
int uploadLimit = -1;
|
int uploadLimit = -1;
|
||||||
int downloadLimit = -1;
|
int downloadLimit = -1;
|
||||||
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||||
|
int inactiveSeedingTimeLimit = Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
||||||
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -219,6 +219,7 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorre
|
|||||||
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", Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||||
|
torrentParams.inactiveSeedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-inactiveSeedingTimeLimit", Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
||||||
|
|
||||||
torrentParams.savePath = Profile::instance()->fromPortablePath(
|
torrentParams.savePath = Profile::instance()->fromPortablePath(
|
||||||
Path(fromLTString(resumeDataRoot.dict_find_string_value("qBt-savePath"))));
|
Path(fromLTString(resumeDataRoot.dict_find_string_value("qBt-savePath"))));
|
||||||
@ -389,6 +390,7 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co
|
|||||||
|
|
||||||
data["qBt-ratioLimit"] = static_cast<int>(resumeData.ratioLimit * 1000);
|
data["qBt-ratioLimit"] = static_cast<int>(resumeData.ratioLimit * 1000);
|
||||||
data["qBt-seedingTimeLimit"] = resumeData.seedingTimeLimit;
|
data["qBt-seedingTimeLimit"] = resumeData.seedingTimeLimit;
|
||||||
|
data["qBt-inactiveSeedingTimeLimit"] = resumeData.inactiveSeedingTimeLimit;
|
||||||
data["qBt-category"] = resumeData.category.toStdString();
|
data["qBt-category"] = resumeData.category.toStdString();
|
||||||
data["qBt-tags"] = setToEntryList(resumeData.tags);
|
data["qBt-tags"] = setToEntryList(resumeData.tags);
|
||||||
data["qBt-name"] = resumeData.name.toStdString();
|
data["qBt-name"] = resumeData.name.toStdString();
|
||||||
|
@ -66,7 +66,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const QString DB_CONNECTION_NAME = u"ResumeDataStorage"_s;
|
const QString DB_CONNECTION_NAME = u"ResumeDataStorage"_s;
|
||||||
|
|
||||||
const int DB_VERSION = 4;
|
const int DB_VERSION = 5;
|
||||||
|
|
||||||
const QString DB_TABLE_META = u"meta"_s;
|
const QString DB_TABLE_META = u"meta"_s;
|
||||||
const QString DB_TABLE_TORRENTS = u"torrents"_s;
|
const QString DB_TABLE_TORRENTS = u"torrents"_s;
|
||||||
@ -135,6 +135,7 @@ namespace
|
|||||||
const Column DB_COLUMN_CONTENT_LAYOUT = makeColumn("content_layout");
|
const Column DB_COLUMN_CONTENT_LAYOUT = makeColumn("content_layout");
|
||||||
const Column DB_COLUMN_RATIO_LIMIT = makeColumn("ratio_limit");
|
const Column DB_COLUMN_RATIO_LIMIT = makeColumn("ratio_limit");
|
||||||
const Column DB_COLUMN_SEEDING_TIME_LIMIT = makeColumn("seeding_time_limit");
|
const Column DB_COLUMN_SEEDING_TIME_LIMIT = makeColumn("seeding_time_limit");
|
||||||
|
const Column DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT = makeColumn("inactive_seeding_time_limit");
|
||||||
const Column DB_COLUMN_HAS_OUTER_PIECES_PRIORITY = makeColumn("has_outer_pieces_priority");
|
const Column DB_COLUMN_HAS_OUTER_PIECES_PRIORITY = makeColumn("has_outer_pieces_priority");
|
||||||
const Column DB_COLUMN_HAS_SEED_STATUS = makeColumn("has_seed_status");
|
const Column DB_COLUMN_HAS_SEED_STATUS = makeColumn("has_seed_status");
|
||||||
const Column DB_COLUMN_OPERATING_MODE = makeColumn("operating_mode");
|
const Column DB_COLUMN_OPERATING_MODE = makeColumn("operating_mode");
|
||||||
@ -228,6 +229,7 @@ namespace
|
|||||||
resumeData.firstLastPiecePriority = query.value(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY.name).toBool();
|
resumeData.firstLastPiecePriority = query.value(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY.name).toBool();
|
||||||
resumeData.ratioLimit = query.value(DB_COLUMN_RATIO_LIMIT.name).toInt() / 1000.0;
|
resumeData.ratioLimit = query.value(DB_COLUMN_RATIO_LIMIT.name).toInt() / 1000.0;
|
||||||
resumeData.seedingTimeLimit = query.value(DB_COLUMN_SEEDING_TIME_LIMIT.name).toInt();
|
resumeData.seedingTimeLimit = query.value(DB_COLUMN_SEEDING_TIME_LIMIT.name).toInt();
|
||||||
|
resumeData.inactiveSeedingTimeLimit = query.value(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT.name).toInt();
|
||||||
resumeData.contentLayout = Utils::String::toEnum<TorrentContentLayout>(
|
resumeData.contentLayout = Utils::String::toEnum<TorrentContentLayout>(
|
||||||
query.value(DB_COLUMN_CONTENT_LAYOUT.name).toString(), TorrentContentLayout::Original);
|
query.value(DB_COLUMN_CONTENT_LAYOUT.name).toString(), TorrentContentLayout::Original);
|
||||||
resumeData.operatingMode = Utils::String::toEnum<TorrentOperatingMode>(
|
resumeData.operatingMode = Utils::String::toEnum<TorrentOperatingMode>(
|
||||||
@ -527,6 +529,7 @@ void BitTorrent::DBResumeDataStorage::createDB() const
|
|||||||
makeColumnDefinition(DB_COLUMN_CONTENT_LAYOUT, "TEXT NOT NULL"),
|
makeColumnDefinition(DB_COLUMN_CONTENT_LAYOUT, "TEXT NOT NULL"),
|
||||||
makeColumnDefinition(DB_COLUMN_RATIO_LIMIT, "INTEGER NOT NULL"),
|
makeColumnDefinition(DB_COLUMN_RATIO_LIMIT, "INTEGER NOT NULL"),
|
||||||
makeColumnDefinition(DB_COLUMN_SEEDING_TIME_LIMIT, "INTEGER NOT NULL"),
|
makeColumnDefinition(DB_COLUMN_SEEDING_TIME_LIMIT, "INTEGER NOT NULL"),
|
||||||
|
makeColumnDefinition(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT, "INTEGER NOT NULL"),
|
||||||
makeColumnDefinition(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY, "INTEGER NOT NULL"),
|
makeColumnDefinition(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY, "INTEGER NOT NULL"),
|
||||||
makeColumnDefinition(DB_COLUMN_HAS_SEED_STATUS, "INTEGER NOT NULL"),
|
makeColumnDefinition(DB_COLUMN_HAS_SEED_STATUS, "INTEGER NOT NULL"),
|
||||||
makeColumnDefinition(DB_COLUMN_OPERATING_MODE, "TEXT NOT NULL"),
|
makeColumnDefinition(DB_COLUMN_OPERATING_MODE, "TEXT NOT NULL"),
|
||||||
@ -606,6 +609,14 @@ void BitTorrent::DBResumeDataStorage::updateDB(const int fromVersion) const
|
|||||||
throw RuntimeError(query.lastError().text());
|
throw RuntimeError(query.lastError().text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fromVersion <= 4)
|
||||||
|
{
|
||||||
|
const auto alterTableTorrentsQuery = u"ALTER TABLE %1 ADD %2"_s
|
||||||
|
.arg(quoted(DB_TABLE_TORRENTS), makeColumnDefinition(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT, "INTEGER NOT NULL"));
|
||||||
|
if (!query.exec(alterTableTorrentsQuery))
|
||||||
|
throw RuntimeError(query.lastError().text());
|
||||||
|
}
|
||||||
|
|
||||||
const QString updateMetaVersionQuery = makeUpdateStatement(DB_TABLE_META, {DB_COLUMN_NAME, DB_COLUMN_VALUE});
|
const QString updateMetaVersionQuery = makeUpdateStatement(DB_TABLE_META, {DB_COLUMN_NAME, DB_COLUMN_VALUE});
|
||||||
if (!query.prepare(updateMetaVersionQuery))
|
if (!query.prepare(updateMetaVersionQuery))
|
||||||
throw RuntimeError(query.lastError().text());
|
throw RuntimeError(query.lastError().text());
|
||||||
@ -782,6 +793,7 @@ namespace
|
|||||||
DB_COLUMN_CONTENT_LAYOUT,
|
DB_COLUMN_CONTENT_LAYOUT,
|
||||||
DB_COLUMN_RATIO_LIMIT,
|
DB_COLUMN_RATIO_LIMIT,
|
||||||
DB_COLUMN_SEEDING_TIME_LIMIT,
|
DB_COLUMN_SEEDING_TIME_LIMIT,
|
||||||
|
DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT,
|
||||||
DB_COLUMN_HAS_OUTER_PIECES_PRIORITY,
|
DB_COLUMN_HAS_OUTER_PIECES_PRIORITY,
|
||||||
DB_COLUMN_HAS_SEED_STATUS,
|
DB_COLUMN_HAS_SEED_STATUS,
|
||||||
DB_COLUMN_OPERATING_MODE,
|
DB_COLUMN_OPERATING_MODE,
|
||||||
@ -840,6 +852,7 @@ namespace
|
|||||||
query.bindValue(DB_COLUMN_CONTENT_LAYOUT.placeholder, Utils::String::fromEnum(m_resumeData.contentLayout));
|
query.bindValue(DB_COLUMN_CONTENT_LAYOUT.placeholder, Utils::String::fromEnum(m_resumeData.contentLayout));
|
||||||
query.bindValue(DB_COLUMN_RATIO_LIMIT.placeholder, static_cast<int>(m_resumeData.ratioLimit * 1000));
|
query.bindValue(DB_COLUMN_RATIO_LIMIT.placeholder, static_cast<int>(m_resumeData.ratioLimit * 1000));
|
||||||
query.bindValue(DB_COLUMN_SEEDING_TIME_LIMIT.placeholder, m_resumeData.seedingTimeLimit);
|
query.bindValue(DB_COLUMN_SEEDING_TIME_LIMIT.placeholder, m_resumeData.seedingTimeLimit);
|
||||||
|
query.bindValue(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT.placeholder, m_resumeData.inactiveSeedingTimeLimit);
|
||||||
query.bindValue(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY.placeholder, m_resumeData.firstLastPiecePriority);
|
query.bindValue(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY.placeholder, m_resumeData.firstLastPiecePriority);
|
||||||
query.bindValue(DB_COLUMN_HAS_SEED_STATUS.placeholder, m_resumeData.hasFinishedStatus);
|
query.bindValue(DB_COLUMN_HAS_SEED_STATUS.placeholder, m_resumeData.hasFinishedStatus);
|
||||||
query.bindValue(DB_COLUMN_OPERATING_MODE.placeholder, Utils::String::fromEnum(m_resumeData.operatingMode));
|
query.bindValue(DB_COLUMN_OPERATING_MODE.placeholder, Utils::String::fromEnum(m_resumeData.operatingMode));
|
||||||
|
@ -60,5 +60,6 @@ namespace BitTorrent
|
|||||||
|
|
||||||
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||||
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||||
|
int inactiveSeedingTimeLimit = Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -203,6 +203,8 @@ namespace BitTorrent
|
|||||||
virtual void setGlobalMaxRatio(qreal ratio) = 0;
|
virtual void setGlobalMaxRatio(qreal ratio) = 0;
|
||||||
virtual int globalMaxSeedingMinutes() const = 0;
|
virtual int globalMaxSeedingMinutes() const = 0;
|
||||||
virtual void setGlobalMaxSeedingMinutes(int minutes) = 0;
|
virtual void setGlobalMaxSeedingMinutes(int minutes) = 0;
|
||||||
|
virtual int globalMaxInactiveSeedingMinutes() const = 0;
|
||||||
|
virtual void setGlobalMaxInactiveSeedingMinutes(int minutes) = 0;
|
||||||
virtual bool isDHTEnabled() const = 0;
|
virtual bool isDHTEnabled() const = 0;
|
||||||
virtual void setDHTEnabled(bool enabled) = 0;
|
virtual void setDHTEnabled(bool enabled) = 0;
|
||||||
virtual bool isLSDEnabled() const = 0;
|
virtual bool isLSDEnabled() const = 0;
|
||||||
|
@ -474,6 +474,7 @@ SessionImpl::SessionImpl(QObject *parent)
|
|||||||
, m_additionalTrackers(BITTORRENT_SESSION_KEY(u"AdditionalTrackers"_s))
|
, m_additionalTrackers(BITTORRENT_SESSION_KEY(u"AdditionalTrackers"_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), -1, lowerLimited(-1))
|
, m_globalMaxSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxSeedingMinutes"_s), -1, lowerLimited(-1))
|
||||||
|
, m_globalMaxInactiveSeedingMinutes(BITTORRENT_SESSION_KEY(u"GlobalMaxInactiveSeedingMinutes"_s), -1, lowerLimited(-1))
|
||||||
, m_isAddTorrentToQueueTop(BITTORRENT_SESSION_KEY(u"AddTorrentToTopOfQueue"_s), false)
|
, m_isAddTorrentToQueueTop(BITTORRENT_SESSION_KEY(u"AddTorrentToTopOfQueue"_s), false)
|
||||||
, m_isAddTorrentPaused(BITTORRENT_SESSION_KEY(u"AddTorrentPaused"_s), false)
|
, m_isAddTorrentPaused(BITTORRENT_SESSION_KEY(u"AddTorrentPaused"_s), false)
|
||||||
, m_torrentStopCondition(BITTORRENT_SESSION_KEY(u"TorrentStopCondition"_s), Torrent::StopCondition::None)
|
, m_torrentStopCondition(BITTORRENT_SESSION_KEY(u"TorrentStopCondition"_s), Torrent::StopCondition::None)
|
||||||
@ -1118,6 +1119,22 @@ void SessionImpl::setGlobalMaxSeedingMinutes(int minutes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SessionImpl::globalMaxInactiveSeedingMinutes() const
|
||||||
|
{
|
||||||
|
return m_globalMaxInactiveSeedingMinutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionImpl::setGlobalMaxInactiveSeedingMinutes(int minutes)
|
||||||
|
{
|
||||||
|
minutes = std::max(minutes, -1);
|
||||||
|
|
||||||
|
if (minutes != globalMaxInactiveSeedingMinutes())
|
||||||
|
{
|
||||||
|
m_globalMaxInactiveSeedingMinutes = minutes;
|
||||||
|
updateSeedingLimitTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SessionImpl::applyBandwidthLimits()
|
void SessionImpl::applyBandwidthLimits()
|
||||||
{
|
{
|
||||||
lt::settings_pack settingsPack;
|
lt::settings_pack settingsPack;
|
||||||
@ -2213,6 +2230,47 @@ void SessionImpl::processShareLimits()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (torrent->inactiveSeedingTimeLimit() != Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT)
|
||||||
|
{
|
||||||
|
const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60;
|
||||||
|
int inactiveSeedingTimeLimit = torrent->inactiveSeedingTimeLimit();
|
||||||
|
if (inactiveSeedingTimeLimit == Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME)
|
||||||
|
{
|
||||||
|
// If Global Seeding Time Limit is really set...
|
||||||
|
inactiveSeedingTimeLimit = globalMaxInactiveSeedingMinutes();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inactiveSeedingTimeLimit >= 0)
|
||||||
|
{
|
||||||
|
if ((inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit))
|
||||||
|
{
|
||||||
|
const QString description = tr("Torrent reached the inactive seeding time limit.");
|
||||||
|
const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
|
||||||
|
|
||||||
|
if (m_maxRatioAction == Remove)
|
||||||
|
{
|
||||||
|
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent."), torrentName));
|
||||||
|
deleteTorrent(torrent->id());
|
||||||
|
}
|
||||||
|
else if (m_maxRatioAction == DeleteFiles)
|
||||||
|
{
|
||||||
|
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent and deleted its content."), torrentName));
|
||||||
|
deleteTorrent(torrent->id(), DeleteTorrentAndFiles);
|
||||||
|
}
|
||||||
|
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
||||||
|
{
|
||||||
|
torrent->pause();
|
||||||
|
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Torrent paused."), torrentName));
|
||||||
|
}
|
||||||
|
else if ((m_maxRatioAction == EnableSuperSeeding) && !torrent->isPaused() && !torrent->superSeeding())
|
||||||
|
{
|
||||||
|
torrent->setSuperSeeding(true);
|
||||||
|
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Super seeding enabled."), torrentName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4842,7 +4900,8 @@ bool SessionImpl::isKnownTorrent(const InfoHash &infoHash) const
|
|||||||
void SessionImpl::updateSeedingLimitTimer()
|
void SessionImpl::updateSeedingLimitTimer()
|
||||||
{
|
{
|
||||||
if ((globalMaxRatio() == Torrent::NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
|
if ((globalMaxRatio() == Torrent::NO_RATIO_LIMIT) && !hasPerTorrentRatioLimit()
|
||||||
&& (globalMaxSeedingMinutes() == Torrent::NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit())
|
&& (globalMaxSeedingMinutes() == Torrent::NO_SEEDING_TIME_LIMIT) && !hasPerTorrentSeedingTimeLimit()
|
||||||
|
&& (globalMaxInactiveSeedingMinutes() == Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT) && !hasPerTorrentInactiveSeedingTimeLimit())
|
||||||
{
|
{
|
||||||
if (m_seedingLimitTimer->isActive())
|
if (m_seedingLimitTimer->isActive())
|
||||||
m_seedingLimitTimer->stop();
|
m_seedingLimitTimer->stop();
|
||||||
@ -5206,6 +5265,14 @@ bool SessionImpl::hasPerTorrentSeedingTimeLimit() const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SessionImpl::hasPerTorrentInactiveSeedingTimeLimit() const
|
||||||
|
{
|
||||||
|
return std::any_of(m_torrents.cbegin(), m_torrents.cend(), [](const TorrentImpl *torrent)
|
||||||
|
{
|
||||||
|
return (torrent->inactiveSeedingTimeLimit() >= 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void SessionImpl::configureDeferred()
|
void SessionImpl::configureDeferred()
|
||||||
{
|
{
|
||||||
if (m_deferredConfigureScheduled)
|
if (m_deferredConfigureScheduled)
|
||||||
|
@ -182,6 +182,8 @@ namespace BitTorrent
|
|||||||
void setGlobalMaxRatio(qreal ratio) override;
|
void setGlobalMaxRatio(qreal ratio) override;
|
||||||
int globalMaxSeedingMinutes() const override;
|
int globalMaxSeedingMinutes() const override;
|
||||||
void setGlobalMaxSeedingMinutes(int minutes) override;
|
void setGlobalMaxSeedingMinutes(int minutes) override;
|
||||||
|
int globalMaxInactiveSeedingMinutes() const override;
|
||||||
|
void setGlobalMaxInactiveSeedingMinutes(int minutes) override;
|
||||||
bool isDHTEnabled() const override;
|
bool isDHTEnabled() const override;
|
||||||
void setDHTEnabled(bool enabled) override;
|
void setDHTEnabled(bool enabled) override;
|
||||||
bool isLSDEnabled() const override;
|
bool isLSDEnabled() const override;
|
||||||
@ -513,6 +515,7 @@ namespace BitTorrent
|
|||||||
|
|
||||||
bool hasPerTorrentRatioLimit() const;
|
bool hasPerTorrentRatioLimit() const;
|
||||||
bool hasPerTorrentSeedingTimeLimit() const;
|
bool hasPerTorrentSeedingTimeLimit() const;
|
||||||
|
bool hasPerTorrentInactiveSeedingTimeLimit() const;
|
||||||
|
|
||||||
// Session configuration
|
// Session configuration
|
||||||
Q_INVOKABLE void configure();
|
Q_INVOKABLE void configure();
|
||||||
@ -660,6 +663,7 @@ namespace BitTorrent
|
|||||||
CachedSettingValue<QString> m_additionalTrackers;
|
CachedSettingValue<QString> m_additionalTrackers;
|
||||||
CachedSettingValue<qreal> m_globalMaxRatio;
|
CachedSettingValue<qreal> m_globalMaxRatio;
|
||||||
CachedSettingValue<int> m_globalMaxSeedingMinutes;
|
CachedSettingValue<int> m_globalMaxSeedingMinutes;
|
||||||
|
CachedSettingValue<int> m_globalMaxInactiveSeedingMinutes;
|
||||||
CachedSettingValue<bool> m_isAddTorrentToQueueTop;
|
CachedSettingValue<bool> m_isAddTorrentToQueueTop;
|
||||||
CachedSettingValue<bool> m_isAddTorrentPaused;
|
CachedSettingValue<bool> m_isAddTorrentPaused;
|
||||||
CachedSettingValue<Torrent::StopCondition> m_torrentStopCondition;
|
CachedSettingValue<Torrent::StopCondition> m_torrentStopCondition;
|
||||||
|
@ -52,8 +52,12 @@ namespace BitTorrent
|
|||||||
const int Torrent::USE_GLOBAL_SEEDING_TIME = -2;
|
const int Torrent::USE_GLOBAL_SEEDING_TIME = -2;
|
||||||
const int Torrent::NO_SEEDING_TIME_LIMIT = -1;
|
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 = 9999;
|
const qreal Torrent::MAX_RATIO = 9999;
|
||||||
const int Torrent::MAX_SEEDING_TIME = 525600;
|
const int Torrent::MAX_SEEDING_TIME = 525600;
|
||||||
|
const int Torrent::MAX_INACTIVE_SEEDING_TIME = 525600;
|
||||||
|
|
||||||
TorrentID Torrent::id() const
|
TorrentID Torrent::id() const
|
||||||
{
|
{
|
||||||
|
@ -126,8 +126,12 @@ namespace BitTorrent
|
|||||||
static const int USE_GLOBAL_SEEDING_TIME;
|
static const int USE_GLOBAL_SEEDING_TIME;
|
||||||
static const int NO_SEEDING_TIME_LIMIT;
|
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;
|
||||||
static const int MAX_SEEDING_TIME;
|
static const int MAX_SEEDING_TIME;
|
||||||
|
static const int MAX_INACTIVE_SEEDING_TIME;
|
||||||
|
|
||||||
using TorrentContentHandler::TorrentContentHandler;
|
using TorrentContentHandler::TorrentContentHandler;
|
||||||
|
|
||||||
@ -210,6 +214,7 @@ namespace BitTorrent
|
|||||||
virtual QDateTime addedTime() const = 0;
|
virtual QDateTime addedTime() const = 0;
|
||||||
virtual qreal ratioLimit() const = 0;
|
virtual qreal ratioLimit() const = 0;
|
||||||
virtual int seedingTimeLimit() const = 0;
|
virtual int seedingTimeLimit() const = 0;
|
||||||
|
virtual int inactiveSeedingTimeLimit() const = 0;
|
||||||
|
|
||||||
virtual PathList filePaths() const = 0;
|
virtual PathList filePaths() const = 0;
|
||||||
|
|
||||||
@ -264,6 +269,7 @@ namespace BitTorrent
|
|||||||
virtual qreal distributedCopies() const = 0;
|
virtual qreal distributedCopies() const = 0;
|
||||||
virtual qreal maxRatio() const = 0;
|
virtual qreal maxRatio() const = 0;
|
||||||
virtual int maxSeedingTime() const = 0;
|
virtual int maxSeedingTime() const = 0;
|
||||||
|
virtual int maxInactiveSeedingTime() const = 0;
|
||||||
virtual qreal realRatio() const = 0;
|
virtual qreal realRatio() const = 0;
|
||||||
virtual int uploadPayloadRate() const = 0;
|
virtual int uploadPayloadRate() const = 0;
|
||||||
virtual int downloadPayloadRate() const = 0;
|
virtual int downloadPayloadRate() const = 0;
|
||||||
@ -283,6 +289,7 @@ namespace BitTorrent
|
|||||||
virtual void forceRecheck() = 0;
|
virtual void forceRecheck() = 0;
|
||||||
virtual void setRatioLimit(qreal limit) = 0;
|
virtual void setRatioLimit(qreal limit) = 0;
|
||||||
virtual void setSeedingTimeLimit(int limit) = 0;
|
virtual void setSeedingTimeLimit(int limit) = 0;
|
||||||
|
virtual void setInactiveSeedingTimeLimit(int limit) = 0;
|
||||||
virtual void setUploadLimit(int limit) = 0;
|
virtual void setUploadLimit(int limit) = 0;
|
||||||
virtual void setDownloadLimit(int limit) = 0;
|
virtual void setDownloadLimit(int limit) = 0;
|
||||||
virtual void setSuperSeeding(bool enable) = 0;
|
virtual void setSuperSeeding(bool enable) = 0;
|
||||||
|
@ -251,6 +251,7 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession
|
|||||||
, m_tags(params.tags)
|
, m_tags(params.tags)
|
||||||
, m_ratioLimit(params.ratioLimit)
|
, m_ratioLimit(params.ratioLimit)
|
||||||
, m_seedingTimeLimit(params.seedingTimeLimit)
|
, m_seedingTimeLimit(params.seedingTimeLimit)
|
||||||
|
, m_inactiveSeedingTimeLimit(params.inactiveSeedingTimeLimit)
|
||||||
, m_operatingMode(params.operatingMode)
|
, m_operatingMode(params.operatingMode)
|
||||||
, m_contentLayout(params.contentLayout)
|
, m_contentLayout(params.contentLayout)
|
||||||
, m_hasFinishedStatus(params.hasFinishedStatus)
|
, m_hasFinishedStatus(params.hasFinishedStatus)
|
||||||
@ -862,6 +863,11 @@ int TorrentImpl::seedingTimeLimit() const
|
|||||||
return m_seedingTimeLimit;
|
return m_seedingTimeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TorrentImpl::inactiveSeedingTimeLimit() const
|
||||||
|
{
|
||||||
|
return m_inactiveSeedingTimeLimit;
|
||||||
|
}
|
||||||
|
|
||||||
Path TorrentImpl::filePath(const int index) const
|
Path TorrentImpl::filePath(const int index) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(index >= 0);
|
Q_ASSERT(index >= 0);
|
||||||
@ -1165,7 +1171,8 @@ qlonglong TorrentImpl::eta() const
|
|||||||
{
|
{
|
||||||
const qreal maxRatioValue = maxRatio();
|
const qreal maxRatioValue = maxRatio();
|
||||||
const int maxSeedingTimeValue = maxSeedingTime();
|
const int maxSeedingTimeValue = maxSeedingTime();
|
||||||
if ((maxRatioValue < 0) && (maxSeedingTimeValue < 0)) return MAX_ETA;
|
const int maxInactiveSeedingTimeValue = maxInactiveSeedingTime();
|
||||||
|
if ((maxRatioValue < 0) && (maxSeedingTimeValue < 0) && (maxInactiveSeedingTimeValue < 0)) return MAX_ETA;
|
||||||
|
|
||||||
qlonglong ratioEta = MAX_ETA;
|
qlonglong ratioEta = MAX_ETA;
|
||||||
|
|
||||||
@ -1188,7 +1195,15 @@ qlonglong TorrentImpl::eta() const
|
|||||||
seedingTimeEta = 0;
|
seedingTimeEta = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::min(ratioEta, seedingTimeEta);
|
qlonglong inactiveSeedingTimeEta = MAX_ETA;
|
||||||
|
|
||||||
|
if (maxInactiveSeedingTimeValue >= 0)
|
||||||
|
{
|
||||||
|
inactiveSeedingTimeEta = (maxInactiveSeedingTimeValue * 60) - timeSinceActivity();
|
||||||
|
inactiveSeedingTimeEta = std::max<qlonglong>(inactiveSeedingTimeEta, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::min({ratioEta, seedingTimeEta, inactiveSeedingTimeEta});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!speedAverage.download) return MAX_ETA;
|
if (!speedAverage.download) return MAX_ETA;
|
||||||
@ -1385,6 +1400,14 @@ int TorrentImpl::maxSeedingTime() const
|
|||||||
return m_seedingTimeLimit;
|
return m_seedingTimeLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TorrentImpl::maxInactiveSeedingTime() const
|
||||||
|
{
|
||||||
|
if (m_inactiveSeedingTimeLimit == USE_GLOBAL_INACTIVE_SEEDING_TIME)
|
||||||
|
return m_session->globalMaxInactiveSeedingMinutes();
|
||||||
|
|
||||||
|
return m_inactiveSeedingTimeLimit;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -2014,6 +2037,7 @@ void TorrentImpl::prepareResumeData(const lt::add_torrent_params ¶ms)
|
|||||||
resumeData.contentLayout = m_contentLayout;
|
resumeData.contentLayout = m_contentLayout;
|
||||||
resumeData.ratioLimit = m_ratioLimit;
|
resumeData.ratioLimit = m_ratioLimit;
|
||||||
resumeData.seedingTimeLimit = m_seedingTimeLimit;
|
resumeData.seedingTimeLimit = m_seedingTimeLimit;
|
||||||
|
resumeData.inactiveSeedingTimeLimit = m_inactiveSeedingTimeLimit;
|
||||||
resumeData.firstLastPiecePriority = m_hasFirstLastPiecePriority;
|
resumeData.firstLastPiecePriority = m_hasFirstLastPiecePriority;
|
||||||
resumeData.hasFinishedStatus = m_hasFinishedStatus;
|
resumeData.hasFinishedStatus = m_hasFinishedStatus;
|
||||||
resumeData.stopped = m_isStopped;
|
resumeData.stopped = m_isStopped;
|
||||||
@ -2406,6 +2430,21 @@ void TorrentImpl::setSeedingTimeLimit(int limit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TorrentImpl::setInactiveSeedingTimeLimit(int limit)
|
||||||
|
{
|
||||||
|
if (limit < USE_GLOBAL_INACTIVE_SEEDING_TIME)
|
||||||
|
limit = NO_INACTIVE_SEEDING_TIME_LIMIT;
|
||||||
|
else if (limit > MAX_INACTIVE_SEEDING_TIME)
|
||||||
|
limit = MAX_SEEDING_TIME;
|
||||||
|
|
||||||
|
if (m_inactiveSeedingTimeLimit != limit)
|
||||||
|
{
|
||||||
|
m_inactiveSeedingTimeLimit = limit;
|
||||||
|
m_session->handleTorrentNeedSaveResumeData(this);
|
||||||
|
m_session->handleTorrentShareLimitChanged(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentImpl::setUploadLimit(const int limit)
|
void TorrentImpl::setUploadLimit(const int limit)
|
||||||
{
|
{
|
||||||
const int cleanValue = cleanLimitValue(limit);
|
const int cleanValue = cleanLimitValue(limit);
|
||||||
|
@ -138,6 +138,7 @@ namespace BitTorrent
|
|||||||
QDateTime addedTime() const override;
|
QDateTime addedTime() const override;
|
||||||
qreal ratioLimit() const override;
|
qreal ratioLimit() const override;
|
||||||
int seedingTimeLimit() const override;
|
int seedingTimeLimit() const override;
|
||||||
|
int inactiveSeedingTimeLimit() 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;
|
||||||
@ -198,6 +199,7 @@ namespace BitTorrent
|
|||||||
qreal distributedCopies() const override;
|
qreal distributedCopies() const override;
|
||||||
qreal maxRatio() const override;
|
qreal maxRatio() const override;
|
||||||
int maxSeedingTime() const override;
|
int maxSeedingTime() const override;
|
||||||
|
int maxInactiveSeedingTime() const override;
|
||||||
qreal realRatio() const override;
|
qreal realRatio() const override;
|
||||||
int uploadPayloadRate() const override;
|
int uploadPayloadRate() const override;
|
||||||
int downloadPayloadRate() const override;
|
int downloadPayloadRate() const override;
|
||||||
@ -220,6 +222,7 @@ namespace BitTorrent
|
|||||||
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
||||||
void setRatioLimit(qreal limit) override;
|
void setRatioLimit(qreal limit) override;
|
||||||
void setSeedingTimeLimit(int limit) override;
|
void setSeedingTimeLimit(int limit) override;
|
||||||
|
void setInactiveSeedingTimeLimit(int limit) override;
|
||||||
void setUploadLimit(int limit) override;
|
void setUploadLimit(int limit) override;
|
||||||
void setDownloadLimit(int limit) override;
|
void setDownloadLimit(int limit) override;
|
||||||
void setSuperSeeding(bool enable) override;
|
void setSuperSeeding(bool enable) override;
|
||||||
@ -345,6 +348,7 @@ namespace BitTorrent
|
|||||||
TagSet m_tags;
|
TagSet m_tags;
|
||||||
qreal m_ratioLimit;
|
qreal m_ratioLimit;
|
||||||
int m_seedingTimeLimit;
|
int m_seedingTimeLimit;
|
||||||
|
int m_inactiveSeedingTimeLimit;
|
||||||
TorrentOperatingMode m_operatingMode;
|
TorrentOperatingMode m_operatingMode;
|
||||||
TorrentContentLayout m_contentLayout;
|
TorrentContentLayout m_contentLayout;
|
||||||
bool m_hasFinishedStatus;
|
bool m_hasFinishedStatus;
|
||||||
|
@ -1048,7 +1048,20 @@ void OptionsDialog::loadBittorrentTabOptions()
|
|||||||
m_ui->checkMaxSeedingMinutes->setChecked(false);
|
m_ui->checkMaxSeedingMinutes->setChecked(false);
|
||||||
m_ui->spinMaxSeedingMinutes->setEnabled(false);
|
m_ui->spinMaxSeedingMinutes->setEnabled(false);
|
||||||
}
|
}
|
||||||
m_ui->comboRatioLimitAct->setEnabled((session->globalMaxSeedingMinutes() >= 0) || (session->globalMaxRatio() >= 0.));
|
if (session->globalMaxInactiveSeedingMinutes() >= 0)
|
||||||
|
{
|
||||||
|
// Enable
|
||||||
|
m_ui->checkMaxInactiveSeedingMinutes->setChecked(true);
|
||||||
|
m_ui->spinMaxInactiveSeedingMinutes->setEnabled(true);
|
||||||
|
m_ui->spinMaxInactiveSeedingMinutes->setValue(session->globalMaxInactiveSeedingMinutes());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Disable
|
||||||
|
m_ui->checkMaxInactiveSeedingMinutes->setChecked(false);
|
||||||
|
m_ui->spinMaxInactiveSeedingMinutes->setEnabled(false);
|
||||||
|
}
|
||||||
|
m_ui->comboRatioLimitAct->setEnabled((session->globalMaxSeedingMinutes() >= 0) || (session->globalMaxRatio() >= 0.) || (session->globalMaxInactiveSeedingMinutes() >= 0));
|
||||||
|
|
||||||
const QHash<MaxRatioAction, int> actIndex =
|
const QHash<MaxRatioAction, int> actIndex =
|
||||||
{
|
{
|
||||||
@ -1088,6 +1101,10 @@ void OptionsDialog::loadBittorrentTabOptions()
|
|||||||
connect(m_ui->checkMaxSeedingMinutes, &QAbstractButton::toggled, this, &ThisType::toggleComboRatioLimitAct);
|
connect(m_ui->checkMaxSeedingMinutes, &QAbstractButton::toggled, this, &ThisType::toggleComboRatioLimitAct);
|
||||||
connect(m_ui->checkMaxSeedingMinutes, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->checkMaxSeedingMinutes, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->spinMaxSeedingMinutes, qSpinBoxValueChanged, this, &ThisType::enableApplyButton);
|
connect(m_ui->spinMaxSeedingMinutes, qSpinBoxValueChanged, this, &ThisType::enableApplyButton);
|
||||||
|
connect(m_ui->checkMaxInactiveSeedingMinutes, &QAbstractButton::toggled, m_ui->spinMaxInactiveSeedingMinutes, &QWidget::setEnabled);
|
||||||
|
connect(m_ui->checkMaxInactiveSeedingMinutes, &QAbstractButton::toggled, this, &ThisType::toggleComboRatioLimitAct);
|
||||||
|
connect(m_ui->checkMaxInactiveSeedingMinutes, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||||
|
connect(m_ui->spinMaxInactiveSeedingMinutes, qSpinBoxValueChanged, this, &ThisType::enableApplyButton);
|
||||||
|
|
||||||
connect(m_ui->checkEnableAddTrackers, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
connect(m_ui->checkEnableAddTrackers, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
|
||||||
connect(m_ui->textTrackers, &QPlainTextEdit::textChanged, this, &ThisType::enableApplyButton);
|
connect(m_ui->textTrackers, &QPlainTextEdit::textChanged, this, &ThisType::enableApplyButton);
|
||||||
@ -1116,6 +1133,7 @@ void OptionsDialog::saveBittorrentTabOptions() const
|
|||||||
|
|
||||||
session->setGlobalMaxRatio(getMaxRatio());
|
session->setGlobalMaxRatio(getMaxRatio());
|
||||||
session->setGlobalMaxSeedingMinutes(getMaxSeedingMinutes());
|
session->setGlobalMaxSeedingMinutes(getMaxSeedingMinutes());
|
||||||
|
session->setGlobalMaxInactiveSeedingMinutes(getMaxInactiveSeedingMinutes());
|
||||||
const QVector<MaxRatioAction> actIndex =
|
const QVector<MaxRatioAction> actIndex =
|
||||||
{
|
{
|
||||||
Pause,
|
Pause,
|
||||||
@ -1443,6 +1461,14 @@ int OptionsDialog::getMaxSeedingMinutes() const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return Inactive Seeding Minutes
|
||||||
|
int OptionsDialog::getMaxInactiveSeedingMinutes() const
|
||||||
|
{
|
||||||
|
return m_ui->checkMaxInactiveSeedingMinutes->isChecked()
|
||||||
|
? m_ui->spinMaxInactiveSeedingMinutes->value()
|
||||||
|
: -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Return max connections number
|
// Return max connections number
|
||||||
int OptionsDialog::getMaxConnections() const
|
int OptionsDialog::getMaxConnections() const
|
||||||
{
|
{
|
||||||
@ -1547,7 +1573,7 @@ void OptionsDialog::enableApplyButton()
|
|||||||
void OptionsDialog::toggleComboRatioLimitAct()
|
void OptionsDialog::toggleComboRatioLimitAct()
|
||||||
{
|
{
|
||||||
// Verify if the share action button must be enabled
|
// Verify if the share action button must be enabled
|
||||||
m_ui->comboRatioLimitAct->setEnabled(m_ui->checkMaxRatio->isChecked() || m_ui->checkMaxSeedingMinutes->isChecked());
|
m_ui->comboRatioLimitAct->setEnabled(m_ui->checkMaxRatio->isChecked() || m_ui->checkMaxSeedingMinutes->isChecked() || m_ui->checkMaxInactiveSeedingMinutes->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptionsDialog::adjustProxyOptions()
|
void OptionsDialog::adjustProxyOptions()
|
||||||
|
@ -166,6 +166,7 @@ private:
|
|||||||
int getEncryptionSetting() const;
|
int getEncryptionSetting() const;
|
||||||
qreal getMaxRatio() const;
|
qreal getMaxRatio() const;
|
||||||
int getMaxSeedingMinutes() const;
|
int getMaxSeedingMinutes() const;
|
||||||
|
int getMaxInactiveSeedingMinutes() const;
|
||||||
// Proxy options
|
// Proxy options
|
||||||
bool isProxyEnabled() const;
|
bool isProxyEnabled() const;
|
||||||
QString getProxyIp() const;
|
QString getProxyIp() const;
|
||||||
|
@ -2899,8 +2899,51 @@ Disable encryption: Only connect to peers without protocol encryption</string>
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Seeding Limits</string>
|
<string>Seeding Limits</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_91">
|
<layout class="QGridLayout" name="gridLayout_15">
|
||||||
<item row="2" column="1">
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkMaxRatio">
|
||||||
|
<property name="text">
|
||||||
|
<string>When ratio reaches</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="spinMaxRatio">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>9998.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.050000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkMaxSeedingMinutes">
|
||||||
|
<property name="text">
|
||||||
|
<string>When total seeding time reaches</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
<widget class="QSpinBox" name="spinMaxSeedingMinutes">
|
<widget class="QSpinBox" name="spinMaxSeedingMinutes">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -2917,9 +2960,25 @@ Disable encryption: Only connect to peers without protocol encryption</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="checkMaxSeedingMinutes">
|
<widget class="QCheckBox" name="checkMaxInactiveSeedingMinutes">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>When seeding time reaches</string>
|
<string>When inactive seeding time reaches</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="spinMaxInactiveSeedingMinutes">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string extracomment="minutes"> min</string>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>9999999</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1440</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -2960,42 +3019,6 @@ Disable encryption: Only connect to peers without protocol encryption</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkMaxRatio">
|
|
||||||
<property name="text">
|
|
||||||
<string>When ratio reaches</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QDoubleSpinBox" name="spinMaxRatio">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>9998.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.050000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -266,6 +266,7 @@ void TorrentCreatorDialog::handleCreationSuccess(const Path &path, const Path &b
|
|||||||
{
|
{
|
||||||
params.ratioLimit = BitTorrent::Torrent::NO_RATIO_LIMIT;
|
params.ratioLimit = BitTorrent::Torrent::NO_RATIO_LIMIT;
|
||||||
params.seedingTimeLimit = BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT;
|
params.seedingTimeLimit = BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT;
|
||||||
|
params.inactiveSeedingTimeLimit = BitTorrent::Torrent::NO_INACTIVE_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
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
bool allSameDownLimit = true;
|
bool allSameDownLimit = true;
|
||||||
bool allSameRatio = true;
|
bool allSameRatio = true;
|
||||||
bool allSameSeedingTime = true;
|
bool allSameSeedingTime = true;
|
||||||
|
bool allSameInactiveSeedingTime = true;
|
||||||
bool allTorrentsArePrivate = true;
|
bool allTorrentsArePrivate = true;
|
||||||
bool allSameDHT = true;
|
bool allSameDHT = true;
|
||||||
bool allSamePEX = true;
|
bool allSamePEX = true;
|
||||||
@ -102,6 +103,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
|
|
||||||
const qreal firstTorrentRatio = torrents[0]->ratioLimit();
|
const qreal firstTorrentRatio = torrents[0]->ratioLimit();
|
||||||
const int firstTorrentSeedingTime = torrents[0]->seedingTimeLimit();
|
const int firstTorrentSeedingTime = torrents[0]->seedingTimeLimit();
|
||||||
|
const int firstTorrentInactiveSeedingTime = torrents[0]->inactiveSeedingTimeLimit();
|
||||||
|
|
||||||
const bool isFirstTorrentDHTDisabled = torrents[0]->isDHTDisabled();
|
const bool isFirstTorrentDHTDisabled = torrents[0]->isDHTDisabled();
|
||||||
const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled();
|
const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled();
|
||||||
@ -154,6 +156,11 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
if (torrent->seedingTimeLimit() != firstTorrentSeedingTime)
|
if (torrent->seedingTimeLimit() != firstTorrentSeedingTime)
|
||||||
allSameSeedingTime = false;
|
allSameSeedingTime = false;
|
||||||
}
|
}
|
||||||
|
if (allSameInactiveSeedingTime)
|
||||||
|
{
|
||||||
|
if (torrent->inactiveSeedingTimeLimit() != firstTorrentInactiveSeedingTime)
|
||||||
|
allSameInactiveSeedingTime = false;
|
||||||
|
}
|
||||||
if (allTorrentsArePrivate)
|
if (allTorrentsArePrivate)
|
||||||
{
|
{
|
||||||
if (!torrent->isPrivate())
|
if (!torrent->isPrivate())
|
||||||
@ -280,7 +287,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
&& (firstTorrentRatio == BitTorrent::Torrent::USE_GLOBAL_RATIO)
|
&& (firstTorrentRatio == BitTorrent::Torrent::USE_GLOBAL_RATIO)
|
||||||
&& (firstTorrentSeedingTime == BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
|
&& (firstTorrentSeedingTime == BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||||
|
|
||||||
if (!allSameRatio || !allSameSeedingTime)
|
if (!allSameRatio || !allSameSeedingTime || !allSameInactiveSeedingTime)
|
||||||
{
|
{
|
||||||
m_ui->radioUseGlobalShareLimits->setChecked(false);
|
m_ui->radioUseGlobalShareLimits->setChecked(false);
|
||||||
m_ui->radioNoLimit->setChecked(false);
|
m_ui->radioNoLimit->setChecked(false);
|
||||||
@ -291,7 +298,8 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
m_ui->radioUseGlobalShareLimits->setChecked(true);
|
m_ui->radioUseGlobalShareLimits->setChecked(true);
|
||||||
}
|
}
|
||||||
else if ((firstTorrentRatio == BitTorrent::Torrent::NO_RATIO_LIMIT)
|
else if ((firstTorrentRatio == BitTorrent::Torrent::NO_RATIO_LIMIT)
|
||||||
&& (firstTorrentSeedingTime == BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT))
|
&& (firstTorrentSeedingTime == BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT)
|
||||||
|
&& (firstTorrentInactiveSeedingTime == BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT))
|
||||||
{
|
{
|
||||||
m_ui->radioNoLimit->setChecked(true);
|
m_ui->radioNoLimit->setChecked(true);
|
||||||
}
|
}
|
||||||
@ -302,14 +310,19 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
m_ui->checkMaxRatio->setChecked(true);
|
m_ui->checkMaxRatio->setChecked(true);
|
||||||
if (firstTorrentSeedingTime >= 0)
|
if (firstTorrentSeedingTime >= 0)
|
||||||
m_ui->checkMaxTime->setChecked(true);
|
m_ui->checkMaxTime->setChecked(true);
|
||||||
|
if (firstTorrentInactiveSeedingTime >= 0)
|
||||||
|
m_ui->checkMaxInactiveTime->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const qreal maxRatio = (allSameRatio && (firstTorrentRatio >= 0))
|
const qreal maxRatio = (allSameRatio && (firstTorrentRatio >= 0))
|
||||||
? firstTorrentRatio : session->globalMaxRatio();
|
? firstTorrentRatio : session->globalMaxRatio();
|
||||||
const int maxSeedingTime = (allSameSeedingTime && (firstTorrentSeedingTime >= 0))
|
const int maxSeedingTime = (allSameSeedingTime && (firstTorrentSeedingTime >= 0))
|
||||||
? firstTorrentSeedingTime : session->globalMaxSeedingMinutes();
|
? firstTorrentSeedingTime : session->globalMaxSeedingMinutes();
|
||||||
|
const int maxInactiveSeedingTime = (allSameInactiveSeedingTime && (firstTorrentInactiveSeedingTime >= 0))
|
||||||
|
? firstTorrentInactiveSeedingTime : session->globalMaxInactiveSeedingMinutes();
|
||||||
m_ui->spinRatioLimit->setValue(maxRatio);
|
m_ui->spinRatioLimit->setValue(maxRatio);
|
||||||
m_ui->spinTimeLimit->setValue(maxSeedingTime);
|
m_ui->spinTimeLimit->setValue(maxSeedingTime);
|
||||||
|
m_ui->spinInactiveTimeLimit->setValue(maxInactiveSeedingTime);
|
||||||
|
|
||||||
if (!allTorrentsArePrivate)
|
if (!allTorrentsArePrivate)
|
||||||
{
|
{
|
||||||
@ -360,6 +373,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
m_ui->comboCategory->currentText(),
|
m_ui->comboCategory->currentText(),
|
||||||
getRatio(),
|
getRatio(),
|
||||||
getSeedingTime(),
|
getSeedingTime(),
|
||||||
|
getInactiveSeedingTime(),
|
||||||
m_ui->spinUploadLimit->value(),
|
m_ui->spinUploadLimit->value(),
|
||||||
m_ui->spinDownloadLimit->value(),
|
m_ui->spinDownloadLimit->value(),
|
||||||
m_ui->checkAutoTMM->checkState(),
|
m_ui->checkAutoTMM->checkState(),
|
||||||
@ -390,6 +404,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||||||
|
|
||||||
connect(m_ui->checkMaxRatio, &QCheckBox::toggled, m_ui->spinRatioLimit, &QWidget::setEnabled);
|
connect(m_ui->checkMaxRatio, &QCheckBox::toggled, m_ui->spinRatioLimit, &QWidget::setEnabled);
|
||||||
connect(m_ui->checkMaxTime, &QCheckBox::toggled, m_ui->spinTimeLimit, &QWidget::setEnabled);
|
connect(m_ui->checkMaxTime, &QCheckBox::toggled, m_ui->spinTimeLimit, &QWidget::setEnabled);
|
||||||
|
connect(m_ui->checkMaxInactiveTime, &QCheckBox::toggled, m_ui->spinInactiveTimeLimit, &QSpinBox::setEnabled);
|
||||||
|
|
||||||
connect(m_ui->buttonGroup, &QButtonGroup::idClicked, this, &TorrentOptionsDialog::handleRatioTypeChanged);
|
connect(m_ui->buttonGroup, &QButtonGroup::idClicked, this, &TorrentOptionsDialog::handleRatioTypeChanged);
|
||||||
|
|
||||||
@ -405,7 +420,8 @@ TorrentOptionsDialog::~TorrentOptionsDialog()
|
|||||||
|
|
||||||
void TorrentOptionsDialog::accept()
|
void TorrentOptionsDialog::accept()
|
||||||
{
|
{
|
||||||
if (m_ui->radioTorrentLimit->isChecked() && !m_ui->checkMaxRatio->isChecked() && !m_ui->checkMaxTime->isChecked())
|
if (m_ui->radioTorrentLimit->isChecked() && !m_ui->checkMaxRatio->isChecked()
|
||||||
|
&& !m_ui->checkMaxTime->isChecked() && !m_ui->checkMaxInactiveTime->isChecked())
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("No share limit method selected"), tr("Please select a limit method first"));
|
QMessageBox::critical(this, tr("No share limit method selected"), tr("Please select a limit method first"));
|
||||||
return;
|
return;
|
||||||
@ -462,6 +478,10 @@ void TorrentOptionsDialog::accept()
|
|||||||
if (m_initialValues.seedingTime != seedingTimeLimit)
|
if (m_initialValues.seedingTime != seedingTimeLimit)
|
||||||
torrent->setSeedingTimeLimit(seedingTimeLimit);
|
torrent->setSeedingTimeLimit(seedingTimeLimit);
|
||||||
|
|
||||||
|
const int inactiveSeedingTimeLimit = getInactiveSeedingTime();
|
||||||
|
if (m_initialValues.inactiveSeedingTime != inactiveSeedingTimeLimit)
|
||||||
|
torrent->setInactiveSeedingTimeLimit(inactiveSeedingTimeLimit);
|
||||||
|
|
||||||
if (!torrent->isPrivate())
|
if (!torrent->isPrivate())
|
||||||
{
|
{
|
||||||
if (m_initialValues.disableDHT != m_ui->checkDisableDHT->checkState())
|
if (m_initialValues.disableDHT != m_ui->checkDisableDHT->checkState())
|
||||||
@ -509,6 +529,20 @@ int TorrentOptionsDialog::getSeedingTime() const
|
|||||||
return m_ui->spinTimeLimit->value();
|
return m_ui->spinTimeLimit->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TorrentOptionsDialog::getInactiveSeedingTime() const
|
||||||
|
{
|
||||||
|
if (m_ui->buttonGroup->checkedId() == -1) // No radio button is selected
|
||||||
|
return MIXED_SHARE_LIMITS;
|
||||||
|
|
||||||
|
if (m_ui->radioUseGlobalShareLimits->isChecked())
|
||||||
|
return BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
||||||
|
|
||||||
|
if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxInactiveTime->isChecked())
|
||||||
|
return BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT;
|
||||||
|
|
||||||
|
return m_ui->spinInactiveTimeLimit->value();
|
||||||
|
}
|
||||||
|
|
||||||
void TorrentOptionsDialog::handleCategoryChanged(const int index)
|
void TorrentOptionsDialog::handleCategoryChanged(const int index)
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
@ -588,7 +622,8 @@ void TorrentOptionsDialog::handleUseDownloadPathChanged()
|
|||||||
|
|
||||||
void TorrentOptionsDialog::handleRatioTypeChanged()
|
void TorrentOptionsDialog::handleRatioTypeChanged()
|
||||||
{
|
{
|
||||||
if ((m_initialValues.ratio == MIXED_SHARE_LIMITS) || (m_initialValues.seedingTime == MIXED_SHARE_LIMITS))
|
if ((m_initialValues.ratio == MIXED_SHARE_LIMITS) || (m_initialValues.seedingTime == MIXED_SHARE_LIMITS)
|
||||||
|
|| (m_initialValues.inactiveSeedingTime == MIXED_SHARE_LIMITS))
|
||||||
{
|
{
|
||||||
QAbstractButton *currentRadio = m_ui->buttonGroup->checkedButton();
|
QAbstractButton *currentRadio = m_ui->buttonGroup->checkedButton();
|
||||||
if (currentRadio && (currentRadio == m_previousRadio))
|
if (currentRadio && (currentRadio == m_previousRadio))
|
||||||
@ -603,9 +638,11 @@ void TorrentOptionsDialog::handleRatioTypeChanged()
|
|||||||
|
|
||||||
m_ui->checkMaxRatio->setEnabled(m_ui->radioTorrentLimit->isChecked());
|
m_ui->checkMaxRatio->setEnabled(m_ui->radioTorrentLimit->isChecked());
|
||||||
m_ui->checkMaxTime->setEnabled(m_ui->radioTorrentLimit->isChecked());
|
m_ui->checkMaxTime->setEnabled(m_ui->radioTorrentLimit->isChecked());
|
||||||
|
m_ui->checkMaxInactiveTime->setEnabled(m_ui->radioTorrentLimit->isChecked());
|
||||||
|
|
||||||
m_ui->spinRatioLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxRatio->isChecked());
|
m_ui->spinRatioLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxRatio->isChecked());
|
||||||
m_ui->spinTimeLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxTime->isChecked());
|
m_ui->spinTimeLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxTime->isChecked());
|
||||||
|
m_ui->spinInactiveTimeLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxInactiveTime->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentOptionsDialog::handleUpSpeedLimitChanged()
|
void TorrentOptionsDialog::handleUpSpeedLimitChanged()
|
||||||
|
@ -73,6 +73,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
qreal getRatio() const;
|
qreal getRatio() const;
|
||||||
int getSeedingTime() const;
|
int getSeedingTime() const;
|
||||||
|
int getInactiveSeedingTime() const;
|
||||||
|
|
||||||
QVector<BitTorrent::TorrentID> m_torrentIDs;
|
QVector<BitTorrent::TorrentID> m_torrentIDs;
|
||||||
Ui::TorrentOptionsDialog *m_ui = nullptr;
|
Ui::TorrentOptionsDialog *m_ui = nullptr;
|
||||||
@ -88,6 +89,7 @@ private:
|
|||||||
QString category;
|
QString category;
|
||||||
qreal ratio;
|
qreal ratio;
|
||||||
int seedingTime;
|
int seedingTime;
|
||||||
|
int inactiveSeedingTime;
|
||||||
int upSpeedLimit;
|
int upSpeedLimit;
|
||||||
int downSpeedLimit;
|
int downSpeedLimit;
|
||||||
Qt::CheckState autoTMM;
|
Qt::CheckState autoTMM;
|
||||||
|
@ -188,10 +188,10 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QCheckBox" name="checkMaxTime">
|
<widget class="QCheckBox" name="checkMaxRatio">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>minutes</string>
|
<string>ratio</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -208,6 +208,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkMaxTime">
|
||||||
|
<property name="text">
|
||||||
|
<string>total minutes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<widget class="QSpinBox" name="spinTimeLimit">
|
<widget class="QSpinBox" name="spinTimeLimit">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
@ -231,10 +238,20 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="checkMaxRatio">
|
<widget class="QCheckBox" name="checkMaxInactiveTime">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>ratio</string>
|
<string>inactive minutes</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QSpinBox" name="spinInactiveTimeLimit">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>525600</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1440</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -258,6 +258,8 @@ void AppController::preferencesAction()
|
|||||||
data[u"max_ratio"_s] = session->globalMaxRatio();
|
data[u"max_ratio"_s] = session->globalMaxRatio();
|
||||||
data[u"max_seeding_time_enabled"_s] = (session->globalMaxSeedingMinutes() >= 0.);
|
data[u"max_seeding_time_enabled"_s] = (session->globalMaxSeedingMinutes() >= 0.);
|
||||||
data[u"max_seeding_time"_s] = session->globalMaxSeedingMinutes();
|
data[u"max_seeding_time"_s] = session->globalMaxSeedingMinutes();
|
||||||
|
data[u"max_inactive_seeding_time_enabled"_s] = (session->globalMaxInactiveSeedingMinutes() >= 0.);
|
||||||
|
data[u"max_inactive_seeding_time"_s] = session->globalMaxInactiveSeedingMinutes();
|
||||||
data[u"max_ratio_act"_s] = session->maxRatioAction();
|
data[u"max_ratio_act"_s] = session->maxRatioAction();
|
||||||
// Add trackers
|
// Add trackers
|
||||||
data[u"add_trackers_enabled"_s] = session->isAddTrackersEnabled();
|
data[u"add_trackers_enabled"_s] = session->isAddTrackersEnabled();
|
||||||
@ -739,6 +741,11 @@ void AppController::setPreferencesAction()
|
|||||||
else
|
else
|
||||||
session->setGlobalMaxSeedingMinutes(-1);
|
session->setGlobalMaxSeedingMinutes(-1);
|
||||||
}
|
}
|
||||||
|
if (hasKey(u"max_inactive_seeding_time_enabled"_s))
|
||||||
|
{
|
||||||
|
session->setGlobalMaxInactiveSeedingMinutes(it.value().toBool()
|
||||||
|
? m[u"max_inactive_seeding_time"_s].toInt() : -1);
|
||||||
|
}
|
||||||
if (hasKey(u"max_ratio_act"_s))
|
if (hasKey(u"max_ratio_act"_s))
|
||||||
session->setMaxRatioAction(static_cast<MaxRatioAction>(it.value().toInt()));
|
session->setMaxRatioAction(static_cast<MaxRatioAction>(it.value().toInt()));
|
||||||
// Add trackers
|
// Add trackers
|
||||||
|
@ -148,9 +148,11 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
|
|||||||
{KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()},
|
{KEY_TORRENT_AMOUNT_COMPLETED, torrent.completedSize()},
|
||||||
{KEY_TORRENT_MAX_RATIO, torrent.maxRatio()},
|
{KEY_TORRENT_MAX_RATIO, torrent.maxRatio()},
|
||||||
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()},
|
{KEY_TORRENT_MAX_SEEDING_TIME, torrent.maxSeedingTime()},
|
||||||
|
{KEY_TORRENT_MAX_INACTIVE_SEEDING_TIME, torrent.maxInactiveSeedingTime()},
|
||||||
{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_SEEDING_TIME_LIMIT, torrent.seedingTimeLimit()},
|
{KEY_TORRENT_SEEDING_TIME_LIMIT, torrent.seedingTimeLimit()},
|
||||||
|
{KEY_TORRENT_INACTIVE_SEEDING_TIME_LIMIT, torrent.inactiveSeedingTimeLimit()},
|
||||||
{KEY_TORRENT_LAST_SEEN_COMPLETE_TIME, torrent.lastSeenComplete().toSecsSinceEpoch()},
|
{KEY_TORRENT_LAST_SEEN_COMPLETE_TIME, torrent.lastSeenComplete().toSecsSinceEpoch()},
|
||||||
{KEY_TORRENT_AUTO_TORRENT_MANAGEMENT, torrent.isAutoTMMEnabled()},
|
{KEY_TORRENT_AUTO_TORRENT_MANAGEMENT, torrent.isAutoTMMEnabled()},
|
||||||
{KEY_TORRENT_TIME_ACTIVE, torrent.activeTime()},
|
{KEY_TORRENT_TIME_ACTIVE, torrent.activeTime()},
|
||||||
|
@ -79,8 +79,10 @@ inline const QString KEY_TORRENT_AMOUNT_LEFT = u"amount_left"_s;
|
|||||||
inline const QString KEY_TORRENT_AMOUNT_COMPLETED = u"completed"_s;
|
inline const QString KEY_TORRENT_AMOUNT_COMPLETED = u"completed"_s;
|
||||||
inline const QString KEY_TORRENT_MAX_RATIO = u"max_ratio"_s;
|
inline const QString KEY_TORRENT_MAX_RATIO = u"max_ratio"_s;
|
||||||
inline const QString KEY_TORRENT_MAX_SEEDING_TIME = u"max_seeding_time"_s;
|
inline const QString KEY_TORRENT_MAX_SEEDING_TIME = u"max_seeding_time"_s;
|
||||||
|
inline const QString KEY_TORRENT_MAX_INACTIVE_SEEDING_TIME = u"max_inactive_seeding_time"_s;
|
||||||
inline const QString KEY_TORRENT_RATIO_LIMIT = u"ratio_limit"_s;
|
inline const QString KEY_TORRENT_RATIO_LIMIT = u"ratio_limit"_s;
|
||||||
inline const QString KEY_TORRENT_SEEDING_TIME_LIMIT = u"seeding_time_limit"_s;
|
inline const QString KEY_TORRENT_SEEDING_TIME_LIMIT = u"seeding_time_limit"_s;
|
||||||
|
inline const QString KEY_TORRENT_INACTIVE_SEEDING_TIME_LIMIT = u"inactive_seeding_time_limit"_s;
|
||||||
inline const QString KEY_TORRENT_LAST_SEEN_COMPLETE_TIME = u"seen_complete"_s;
|
inline const QString KEY_TORRENT_LAST_SEEN_COMPLETE_TIME = u"seen_complete"_s;
|
||||||
inline const QString KEY_TORRENT_LAST_ACTIVITY_TIME = u"last_activity"_s;
|
inline const QString KEY_TORRENT_LAST_ACTIVITY_TIME = u"last_activity"_s;
|
||||||
inline const QString KEY_TORRENT_TOTAL_SIZE = u"total_size"_s;
|
inline const QString KEY_TORRENT_TOTAL_SIZE = u"total_size"_s;
|
||||||
|
@ -673,6 +673,7 @@ void TorrentsController::addAction()
|
|||||||
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::Torrent::USE_GLOBAL_RATIO);
|
||||||
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::Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||||
|
const int inactiveSeedingTimeLimit = parseInt(params()[u"inactiveSeedingTimeLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
||||||
const std::optional<bool> autoTMM = parseBool(params()[u"autoTMM"_s]);
|
const std::optional<bool> autoTMM = parseBool(params()[u"autoTMM"_s]);
|
||||||
|
|
||||||
const QString stopConditionParam = params()[u"stopCondition"_s];
|
const QString stopConditionParam = params()[u"stopCondition"_s];
|
||||||
@ -720,6 +721,7 @@ void TorrentsController::addAction()
|
|||||||
addTorrentParams.uploadLimit = upLimit;
|
addTorrentParams.uploadLimit = upLimit;
|
||||||
addTorrentParams.downloadLimit = dlLimit;
|
addTorrentParams.downloadLimit = dlLimit;
|
||||||
addTorrentParams.seedingTimeLimit = seedingTimeLimit;
|
addTorrentParams.seedingTimeLimit = seedingTimeLimit;
|
||||||
|
addTorrentParams.inactiveSeedingTimeLimit = inactiveSeedingTimeLimit;
|
||||||
addTorrentParams.ratioLimit = ratioLimit;
|
addTorrentParams.ratioLimit = ratioLimit;
|
||||||
addTorrentParams.useAutoTMM = autoTMM;
|
addTorrentParams.useAutoTMM = autoTMM;
|
||||||
|
|
||||||
@ -980,16 +982,18 @@ void TorrentsController::setDownloadLimitAction()
|
|||||||
|
|
||||||
void TorrentsController::setShareLimitsAction()
|
void TorrentsController::setShareLimitsAction()
|
||||||
{
|
{
|
||||||
requireParams({u"hashes"_s, u"ratioLimit"_s, u"seedingTimeLimit"_s});
|
requireParams({u"hashes"_s, u"ratioLimit"_s, u"seedingTimeLimit"_s, u"inactiveSeedingTimeLimit"_s});
|
||||||
|
|
||||||
const qreal ratioLimit = params()[u"ratioLimit"_s].toDouble();
|
const qreal ratioLimit = params()[u"ratioLimit"_s].toDouble();
|
||||||
const qlonglong seedingTimeLimit = params()[u"seedingTimeLimit"_s].toLongLong();
|
const qlonglong seedingTimeLimit = params()[u"seedingTimeLimit"_s].toLongLong();
|
||||||
|
const qlonglong inactiveSeedingTimeLimit = params()[u"inactiveSeedingTimeLimit"_s].toLongLong();
|
||||||
const QStringList hashes = params()[u"hashes"_s].split(u'|');
|
const QStringList hashes = params()[u"hashes"_s].split(u'|');
|
||||||
|
|
||||||
applyToTorrents(hashes, [ratioLimit, seedingTimeLimit](BitTorrent::Torrent *const torrent)
|
applyToTorrents(hashes, [ratioLimit, seedingTimeLimit, inactiveSeedingTimeLimit](BitTorrent::Torrent *const torrent)
|
||||||
{
|
{
|
||||||
torrent->setRatioLimit(ratioLimit);
|
torrent->setRatioLimit(ratioLimit);
|
||||||
torrent->setSeedingTimeLimit(seedingTimeLimit);
|
torrent->setSeedingTimeLimit(seedingTimeLimit);
|
||||||
|
torrent->setInactiveSeedingTimeLimit(inactiveSeedingTimeLimit);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,8 @@ const initializeWindows = function() {
|
|||||||
for (let i = 0; i < hashes.length; ++i) {
|
for (let i = 0; i < hashes.length; ++i) {
|
||||||
const hash = hashes[i];
|
const hash = hashes[i];
|
||||||
const row = torrentsTable.rows[hash].full_data;
|
const row = torrentsTable.rows[hash].full_data;
|
||||||
const origValues = row.ratio_limit + "|" + row.seeding_time_limit + "|" + row.max_ratio + "|" + row.max_seeding_time;
|
const origValues = row.ratio_limit + "|" + row.seeding_time_limit + "|" + row.inactive_seeding_time_limit + "|"
|
||||||
|
+ row.max_ratio + "|" + row.max_seeding_time + "|" + row.max_inactive_seeding_time;
|
||||||
|
|
||||||
// initialize value
|
// initialize value
|
||||||
if (shareRatio === null)
|
if (shareRatio === null)
|
||||||
|
@ -39,16 +39,19 @@
|
|||||||
const values = {
|
const values = {
|
||||||
ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
|
ratioLimit: window.qBittorrent.Misc.friendlyFloat(origValues[0], 2),
|
||||||
seedingTimeLimit: parseInt(origValues[1]),
|
seedingTimeLimit: parseInt(origValues[1]),
|
||||||
maxRatio: window.qBittorrent.Misc.friendlyFloat(origValues[2], 2),
|
inactiveSeedingTimeLimit: parseInt(origValues[2]),
|
||||||
maxSeedingTime: parseInt(origValues[3])
|
maxRatio: window.qBittorrent.Misc.friendlyFloat(origValues[3], 2),
|
||||||
|
maxSeedingTime: parseInt(origValues[4]),
|
||||||
|
maxInactiveSeedingTime: parseInt(origValues[5])
|
||||||
};
|
};
|
||||||
|
|
||||||
// select default when orig values not passed. using double equals to compare string and int
|
// select default when orig values not passed. using double equals to compare string and int
|
||||||
if ((origValues[0] === "") || ((values.ratioLimit == UseGlobalLimit) && (values.seedingTimeLimit == UseGlobalLimit))) {
|
if ((origValues[0] === "") || ((values.ratioLimit == UseGlobalLimit) && (values.seedingTimeLimit == UseGlobalLimit))
|
||||||
|
&& (values.inactiveSeedingTimeLimit == UseGlobalLimit)) {
|
||||||
// use default option
|
// use default option
|
||||||
setSelectedRadioValue('shareLimit', 'default');
|
setSelectedRadioValue('shareLimit', 'default');
|
||||||
}
|
}
|
||||||
else if ((values.maxRatio == NoLimit) && (values.maxSeedingTime == NoLimit)) {
|
else if ((values.maxRatio == NoLimit) && (values.maxSeedingTime == NoLimit) && (values.maxInactiveSeedingTime == NoLimit)) {
|
||||||
setSelectedRadioValue('shareLimit', 'none');
|
setSelectedRadioValue('shareLimit', 'none');
|
||||||
// TODO set input boxes to *global* max ratio and seeding time
|
// TODO set input boxes to *global* max ratio and seeding time
|
||||||
}
|
}
|
||||||
@ -59,8 +62,12 @@
|
|||||||
$('ratio').set('value', values.ratioLimit);
|
$('ratio').set('value', values.ratioLimit);
|
||||||
}
|
}
|
||||||
if (values.seedingTimeLimit >= 0) {
|
if (values.seedingTimeLimit >= 0) {
|
||||||
$('setMinutes').set('checked', true);
|
$('setTotalMinutes').set('checked', true);
|
||||||
$('minutes').set('value', values.seedingTimeLimit);
|
$('totalMinutes').set('value', values.seedingTimeLimit);
|
||||||
|
}
|
||||||
|
if (values.inactiveSeedingTimeLimit >= 0) {
|
||||||
|
$('setInactiveMinutes').set('checked', true);
|
||||||
|
$('inactiveMinutes').set('value', values.inactiveSeedingTimeLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,16 +84,18 @@
|
|||||||
const shareLimit = getSelectedRadioValue('shareLimit');
|
const shareLimit = getSelectedRadioValue('shareLimit');
|
||||||
let ratioLimitValue = 0.00;
|
let ratioLimitValue = 0.00;
|
||||||
let seedingTimeLimitValue = 0;
|
let seedingTimeLimitValue = 0;
|
||||||
|
let inactiveSeedingTimeLimitValue = 0;
|
||||||
|
|
||||||
if (shareLimit === 'default') {
|
if (shareLimit === 'default') {
|
||||||
ratioLimitValue = seedingTimeLimitValue = UseGlobalLimit;
|
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = UseGlobalLimit;
|
||||||
}
|
}
|
||||||
else if (shareLimit === 'none') {
|
else if (shareLimit === 'none') {
|
||||||
ratioLimitValue = seedingTimeLimitValue = NoLimit;
|
ratioLimitValue = seedingTimeLimitValue = inactiveSeedingTimeLimitValue = NoLimit;
|
||||||
}
|
}
|
||||||
else if (shareLimit === 'custom') {
|
else if (shareLimit === 'custom') {
|
||||||
ratioLimitValue = $('setRatio').get('checked') ? $('ratio').get('value') : -1;
|
ratioLimitValue = $('setRatio').get('checked') ? $('ratio').get('value') : -1;
|
||||||
seedingTimeLimitValue = $('setMinutes').get('checked') ? $('minutes').get('value') : -1;
|
seedingTimeLimitValue = $('setTotalMinutes').get('checked') ? $('totalMinutes').get('value') : -1;
|
||||||
|
inactiveSeedingTimeLimitValue = $('setInactiveMinutes').get('checked') ? $('inactiveMinutes').get('value') : -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
@ -98,7 +107,8 @@
|
|||||||
data: {
|
data: {
|
||||||
hashes: hashesList.join('|'),
|
hashes: hashesList.join('|'),
|
||||||
ratioLimit: ratioLimitValue,
|
ratioLimit: ratioLimitValue,
|
||||||
seedingTimeLimit: seedingTimeLimitValue
|
seedingTimeLimit: seedingTimeLimitValue,
|
||||||
|
inactiveSeedingTimeLimit: inactiveSeedingTimeLimitValue
|
||||||
},
|
},
|
||||||
onComplete: function() {
|
onComplete: function() {
|
||||||
window.parent.closeWindows();
|
window.parent.closeWindows();
|
||||||
@ -131,7 +141,8 @@
|
|||||||
function shareLimitChanged() {
|
function shareLimitChanged() {
|
||||||
const customShareLimit = getSelectedRadioValue('shareLimit') === 'custom';
|
const customShareLimit = getSelectedRadioValue('shareLimit') === 'custom';
|
||||||
$('setRatio').set('disabled', !customShareLimit);
|
$('setRatio').set('disabled', !customShareLimit);
|
||||||
$('setMinutes').set('disabled', !customShareLimit);
|
$('setTotalMinutes').set('disabled', !customShareLimit);
|
||||||
|
$('setInactiveMinutes').set('disabled', !customShareLimit);
|
||||||
|
|
||||||
enableInputBoxes();
|
enableInputBoxes();
|
||||||
|
|
||||||
@ -140,13 +151,15 @@
|
|||||||
|
|
||||||
function enableInputBoxes() {
|
function enableInputBoxes() {
|
||||||
$('ratio').set('disabled', ($('setRatio').get('disabled') || !$('setRatio').get('checked')));
|
$('ratio').set('disabled', ($('setRatio').get('disabled') || !$('setRatio').get('checked')));
|
||||||
$('minutes').set('disabled', ($('setMinutes').get('disabled') || !$('setMinutes').get('checked')));
|
$('totalMinutes').set('disabled', ($('setTotalMinutes').get('disabled') || !$('setTotalMinutes').get('checked')));
|
||||||
|
$('inactiveMinutes').set('disabled', ($('setInactiveMinutes').get('disabled') || !$('setInactiveMinutes').get('checked')));
|
||||||
|
|
||||||
$('save').set('disabled', !isFormValid());
|
$('save').set('disabled', !isFormValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFormValid() {
|
function isFormValid() {
|
||||||
return !((getSelectedRadioValue('shareLimit') === 'custom') && !$('setRatio').get('checked') && !$('setMinutes').get('checked'));
|
return !((getSelectedRadioValue('shareLimit') === 'custom') && !$('setRatio').get('checked')
|
||||||
|
&& !$('setTotalMinutes').get('checked') && !$('setInactiveMinutes').get('checked'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
@ -163,9 +176,14 @@
|
|||||||
<input type="number" id="ratio" value="0.00" step=".01" min="0" max="9999" class="shareLimitInput" />
|
<input type="number" id="ratio" value="0.00" step=".01" min="0" max="9999" class="shareLimitInput" />
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-left: 40px; margin-bottom: 5px;">
|
<div style="margin-left: 40px; margin-bottom: 5px;">
|
||||||
<input type="checkbox" id="setMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
|
<input type="checkbox" id="setTotalMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
|
||||||
<label for="setMinutes">QBT_TR(minutes)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
|
<label for="setTotalMinutes">QBT_TR(total minutes)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
|
||||||
<input type="number" id="minutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
|
<input type="number" id="totalMinutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
|
||||||
|
</div>
|
||||||
|
<div style="margin-left: 40px; margin-bottom: 5px;">
|
||||||
|
<input type="checkbox" id="setInactiveMinutes" class="shareLimitInput" onclick="enableInputBoxes()" />
|
||||||
|
<label for="setInactiveMinutes">QBT_TR(inactive minutes)QBT_TR[CONTEXT=UpDownRatioDialog]</label>
|
||||||
|
<input type="number" id="inactiveMinutes" value="0" step="1" min="0" max="525600" class="shareLimitInput" />
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: center; padding-top: 10px;">
|
<div style="text-align: center; padding-top: 10px;">
|
||||||
<input type="button" value="QBT_TR(Save)QBT_TR[CONTEXT=HttpServer]" id="save" />
|
<input type="button" value="QBT_TR(Save)QBT_TR[CONTEXT=HttpServer]" id="save" />
|
||||||
|
@ -650,12 +650,21 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox" id="max_seeding_time_checkbox" onclick="qBittorrent.Preferences.updateMaxRatioTimeEnabled();" />
|
<input type="checkbox" id="max_seeding_time_checkbox" onclick="qBittorrent.Preferences.updateMaxRatioTimeEnabled();" />
|
||||||
<label for="max_seeding_time_checkbox">QBT_TR(When seeding time reaches)QBT_TR[CONTEXT=OptionsDialog]</label>
|
<label for="max_seeding_time_checkbox">QBT_TR(When total seeding time reaches)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" id="max_seeding_time_value" style="width: 4em;" />QBT_TR(minutes)QBT_TR[CONTEXT=OptionsDialog]
|
<input type="text" id="max_seeding_time_value" style="width: 4em;" />QBT_TR(minutes)QBT_TR[CONTEXT=OptionsDialog]
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="max_inactive_seeding_time_checkbox" onclick="qBittorrent.Preferences.updateMaxRatioTimeEnabled();" />
|
||||||
|
<label for="max_inactive_seeding_time_checkbox">QBT_TR(When inactive seeding time reaches)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" id="max_inactive_seeding_time_value" style="width: 4em;" />QBT_TR(minutes)QBT_TR[CONTEXT=OptionsDialog]
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: right;"><label for="max_ratio_act">QBT_TR(then)QBT_TR[CONTEXT=OptionsDialog]</label></td>
|
<td style="text-align: right;"><label for="max_ratio_act">QBT_TR(then)QBT_TR[CONTEXT=OptionsDialog]</label></td>
|
||||||
<td>
|
<td>
|
||||||
@ -1700,7 +1709,10 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||||||
const isMaxSeedingTimeEnabled = $('max_seeding_time_checkbox').getProperty('checked');
|
const isMaxSeedingTimeEnabled = $('max_seeding_time_checkbox').getProperty('checked');
|
||||||
$('max_seeding_time_value').setProperty('disabled', !isMaxSeedingTimeEnabled);
|
$('max_seeding_time_value').setProperty('disabled', !isMaxSeedingTimeEnabled);
|
||||||
|
|
||||||
$('max_ratio_act').setProperty('disabled', !(isMaxRatioEnabled || isMaxSeedingTimeEnabled));
|
const isMaxInactiveSeedingTimeEnabled = $('max_inactive_seeding_time_checkbox').getProperty('checked');
|
||||||
|
$('max_inactive_seeding_time_value').setProperty('disabled', !isMaxInactiveSeedingTimeEnabled);
|
||||||
|
|
||||||
|
$('max_ratio_act').setProperty('disabled', !(isMaxRatioEnabled || isMaxSeedingTimeEnabled || isMaxInactiveSeedingTimeEnabled));
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateAddTrackersEnabled = function() {
|
const updateAddTrackersEnabled = function() {
|
||||||
@ -2081,6 +2093,8 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||||||
$('max_ratio_value').setProperty('value', (pref.max_ratio_enabled ? pref.max_ratio : 1));
|
$('max_ratio_value').setProperty('value', (pref.max_ratio_enabled ? pref.max_ratio : 1));
|
||||||
$('max_seeding_time_checkbox').setProperty('checked', pref.max_seeding_time_enabled);
|
$('max_seeding_time_checkbox').setProperty('checked', pref.max_seeding_time_enabled);
|
||||||
$('max_seeding_time_value').setProperty('value', (pref.max_seeding_time_enabled ? pref.max_seeding_time.toInt() : 1440));
|
$('max_seeding_time_value').setProperty('value', (pref.max_seeding_time_enabled ? pref.max_seeding_time.toInt() : 1440));
|
||||||
|
$('max_inactive_seeding_time_checkbox').setProperty('checked', pref.max_inactive_seeding_time_enabled);
|
||||||
|
$('max_inactive_seeding_time_value').setProperty('value', (pref.max_inactive_seeding_time_enabled ? pref.max_inactive_seeding_time.toInt() : 1440));
|
||||||
let maxRatioAct = 0;
|
let maxRatioAct = 0;
|
||||||
switch (pref.max_ratio_act.toInt()) {
|
switch (pref.max_ratio_act.toInt()) {
|
||||||
case 0: // Pause
|
case 0: // Pause
|
||||||
@ -2488,6 +2502,18 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||||||
settings.set('max_seeding_time', max_seeding_time);
|
settings.set('max_seeding_time', max_seeding_time);
|
||||||
settings.set('max_ratio_act', $('max_ratio_act').getProperty('value').toInt());
|
settings.set('max_ratio_act', $('max_ratio_act').getProperty('value').toInt());
|
||||||
|
|
||||||
|
let max_inactive_seeding_time = -1;
|
||||||
|
if ($('max_inactive_seeding_time_checkbox').getProperty('checked')) {
|
||||||
|
max_inactive_seeding_time = $('max_inactive_seeding_time_value').getProperty('value').toInt();
|
||||||
|
if (isNaN(max_inactive_seeding_time) || (max_inactive_seeding_time < 0) || (max_inactive_seeding_time > 525600)) {
|
||||||
|
alert("QBT_TR(Seeding time limit must be between 0 and 525600 minutes.)QBT_TR[CONTEXT=HttpServer]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.set('max_inactive_seeding_time_enabled', $('max_inactive_seeding_time_checkbox').getProperty('checked'));
|
||||||
|
settings.set('max_inactive_seeding_time', max_inactive_seeding_time);
|
||||||
|
settings.set('max_ratio_act', $('max_ratio_act').getProperty('value').toInt());
|
||||||
|
|
||||||
// Add trackers
|
// Add trackers
|
||||||
settings.set('add_trackers_enabled', $('add_trackers_checkbox').getProperty('checked'));
|
settings.set('add_trackers_enabled', $('add_trackers_checkbox').getProperty('checked'));
|
||||||
settings.set('add_trackers', $('add_trackers_textarea').getProperty('value'));
|
settings.set('add_trackers', $('add_trackers_textarea').getProperty('value'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user