Skip to content

Commit

Permalink
Correctly handle share limits in torrent options dialog
Browse files Browse the repository at this point in the history
PR #20485.
  • Loading branch information
glassez authored Mar 4, 2024
1 parent f65af03 commit 1702b6c
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 330 deletions.
11 changes: 6 additions & 5 deletions src/gui/addtorrentparamswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ void AddTorrentParamsWidget::setAddTorrentParams(BitTorrent::AddTorrentParams ad
BitTorrent::AddTorrentParams AddTorrentParamsWidget::addTorrentParams() const
{
BitTorrent::AddTorrentParams addTorrentParams = cleanParams(m_addTorrentParams);
addTorrentParams.ratioLimit = m_ui->torrentShareLimitsWidget->ratioLimit();
addTorrentParams.seedingTimeLimit = m_ui->torrentShareLimitsWidget->seedingTimeLimit();
addTorrentParams.inactiveSeedingTimeLimit = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit();
addTorrentParams.ratioLimit = m_ui->torrentShareLimitsWidget->ratioLimit().value();
addTorrentParams.seedingTimeLimit = m_ui->torrentShareLimitsWidget->seedingTimeLimit().value();
addTorrentParams.inactiveSeedingTimeLimit = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit().value();

return addTorrentParams;
}
Expand Down Expand Up @@ -269,8 +269,9 @@ void AddTorrentParamsWidget::populate()
m_addTorrentParams.addToQueueTop = data.toBool();
});

m_ui->torrentShareLimitsWidget->setTorrentShareLimits(m_addTorrentParams.ratioLimit
, m_addTorrentParams.seedingTimeLimit, m_addTorrentParams.inactiveSeedingTimeLimit);
m_ui->torrentShareLimitsWidget->setRatioLimit(m_addTorrentParams.ratioLimit);
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(m_addTorrentParams.seedingTimeLimit);
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(m_addTorrentParams.inactiveSeedingTimeLimit);
}

void AddTorrentParamsWidget::loadCustomSavePathOptions()
Expand Down
186 changes: 38 additions & 148 deletions src/gui/torrentoptionsdialog.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2020 thalieht
* Copyright (C) 2011 Christian Kandeler
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
Expand Down Expand Up @@ -49,8 +50,6 @@

namespace
{
const int MIXED_SHARE_LIMITS = -9;

void updateSliderValue(QSlider *slider, const int value)
{
if (value > slider->maximum())
Expand Down Expand Up @@ -283,47 +282,13 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
, this, &TorrentOptionsDialog::handleDownSpeedLimitChanged);
}

const bool useGlobalValue = allSameRatio && allSameSeedingTime
&& (firstTorrentRatio == BitTorrent::Torrent::USE_GLOBAL_RATIO)
&& (firstTorrentSeedingTime == BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME)
&& (firstTorrentInactiveSeedingTime == BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);

if (!allSameRatio || !allSameSeedingTime || !allSameInactiveSeedingTime)
{
m_ui->radioUseGlobalShareLimits->setChecked(false);
m_ui->radioNoLimit->setChecked(false);
m_ui->radioTorrentLimit->setChecked(false);
}
else if (useGlobalValue)
{
m_ui->radioUseGlobalShareLimits->setChecked(true);
}
else if ((firstTorrentRatio == BitTorrent::Torrent::NO_RATIO_LIMIT)
&& (firstTorrentSeedingTime == BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT)
&& (firstTorrentInactiveSeedingTime == BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT))
{
m_ui->radioNoLimit->setChecked(true);
}
else
{
m_ui->radioTorrentLimit->setChecked(true);
if (firstTorrentRatio >= 0)
m_ui->checkMaxRatio->setChecked(true);
if (firstTorrentSeedingTime >= 0)
m_ui->checkMaxTime->setChecked(true);
if (firstTorrentInactiveSeedingTime >= 0)
m_ui->checkMaxInactiveTime->setChecked(true);
}

const qreal maxRatio = (allSameRatio && (firstTorrentRatio >= 0))
? firstTorrentRatio : session->globalMaxRatio();
const int maxSeedingTime = (allSameSeedingTime && (firstTorrentSeedingTime >= 0))
? firstTorrentSeedingTime : session->globalMaxSeedingMinutes();
const int maxInactiveSeedingTime = (allSameInactiveSeedingTime && (firstTorrentInactiveSeedingTime >= 0))
? firstTorrentInactiveSeedingTime : session->globalMaxInactiveSeedingMinutes();
m_ui->spinRatioLimit->setValue(maxRatio);
m_ui->spinTimeLimit->setValue(maxSeedingTime);
m_ui->spinInactiveTimeLimit->setValue(maxInactiveSeedingTime);
m_ui->torrentShareLimitsWidget->setDefaultLimits(session->globalMaxRatio(), session->globalMaxSeedingMinutes(), session->globalMaxInactiveSeedingMinutes());
if (allSameRatio)
m_ui->torrentShareLimitsWidget->setRatioLimit(firstTorrentRatio);
if (allSameSeedingTime)
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(firstTorrentSeedingTime);
if (allSameInactiveSeedingTime)
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(firstTorrentInactiveSeedingTime);

if (!allTorrentsArePrivate)
{
Expand Down Expand Up @@ -369,27 +334,26 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor

m_initialValues =
{
m_ui->savePath->selectedPath(),
m_ui->downloadPath->selectedPath(),
m_ui->comboCategory->currentText(),
getRatio(),
getSeedingTime(),
getInactiveSeedingTime(),
m_ui->spinUploadLimit->value(),
m_ui->spinDownloadLimit->value(),
m_ui->checkAutoTMM->checkState(),
m_ui->checkUseDownloadPath->checkState(),
m_ui->checkDisableDHT->checkState(),
m_ui->checkDisablePEX->checkState(),
m_ui->checkDisableLSD->checkState(),
m_ui->checkSequential->checkState(),
m_ui->checkFirstLastPieces->checkState()
.savePath = m_ui->savePath->selectedPath(),
.downloadPath = m_ui->downloadPath->selectedPath(),
.category = m_ui->comboCategory->currentText(),
.ratio = m_ui->torrentShareLimitsWidget->ratioLimit(),
.seedingTime = m_ui->torrentShareLimitsWidget->seedingTimeLimit(),
.inactiveSeedingTime = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit(),
.upSpeedLimit = m_ui->spinUploadLimit->value(),
.downSpeedLimit = m_ui->spinDownloadLimit->value(),
.autoTMM = m_ui->checkAutoTMM->checkState(),
.useDownloadPath = m_ui->checkUseDownloadPath->checkState(),
.disableDHT = m_ui->checkDisableDHT->checkState(),
.disablePEX = m_ui->checkDisablePEX->checkState(),
.disableLSD = m_ui->checkDisableLSD->checkState(),
.sequential = m_ui->checkSequential->checkState(),
.firstLastPieces = m_ui->checkFirstLastPieces->checkState()
};

// Needs to be called after the initial values struct is initialized
handleTMMChanged();
handleUseDownloadPathChanged();
handleRatioTypeChanged();

connect(m_ui->checkAutoTMM, &QCheckBox::clicked, this, &TorrentOptionsDialog::handleTMMChanged);
connect(m_ui->checkUseDownloadPath, &QCheckBox::clicked, this, &TorrentOptionsDialog::handleUseDownloadPathChanged);
Expand All @@ -403,12 +367,6 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
connect(m_ui->spinDownloadLimit, qOverload<int>(&QSpinBox::valueChanged)
, this, [this](const int value) { updateSliderValue(m_ui->sliderDownloadLimit, value); });

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->checkMaxInactiveTime, &QCheckBox::toggled, m_ui->spinInactiveTimeLimit, &QSpinBox::setEnabled);

connect(m_ui->buttonGroup, &QButtonGroup::idClicked, this, &TorrentOptionsDialog::handleRatioTypeChanged);

if (const QSize dialogSize = m_storeDialogSize; dialogSize.isValid())
resize(dialogSize);
}
Expand All @@ -421,13 +379,6 @@ TorrentOptionsDialog::~TorrentOptionsDialog()

void TorrentOptionsDialog::accept()
{
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"));
return;
}

auto *session = BitTorrent::Session::instance();
for (const BitTorrent::TorrentID &id : asConst(m_torrentIDs))
{
Expand Down Expand Up @@ -471,17 +422,23 @@ void TorrentOptionsDialog::accept()
if (m_initialValues.downSpeedLimit != m_ui->spinDownloadLimit->value())
torrent->setDownloadLimit(m_ui->spinDownloadLimit->value() * 1024);

const qreal ratioLimit = getRatio();
if (m_initialValues.ratio != ratioLimit)
torrent->setRatioLimit(ratioLimit);
if (const std::optional<qreal> ratioLimit = m_ui->torrentShareLimitsWidget->ratioLimit();
m_initialValues.ratio != ratioLimit)
{
torrent->setRatioLimit(ratioLimit.value());
}

const int seedingTimeLimit = getSeedingTime();
if (m_initialValues.seedingTime != seedingTimeLimit)
torrent->setSeedingTimeLimit(seedingTimeLimit);
if (const std::optional<int> seedingTimeLimit = m_ui->torrentShareLimitsWidget->seedingTimeLimit();
m_initialValues.seedingTime != seedingTimeLimit)
{
torrent->setSeedingTimeLimit(seedingTimeLimit.value());
}

const int inactiveSeedingTimeLimit = getInactiveSeedingTime();
if (m_initialValues.inactiveSeedingTime != inactiveSeedingTimeLimit)
torrent->setInactiveSeedingTimeLimit(inactiveSeedingTimeLimit);
if (const std::optional<int> inactiveSeedingTimeLimit = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit();
m_initialValues.inactiveSeedingTime != inactiveSeedingTimeLimit)
{
torrent->setInactiveSeedingTimeLimit(inactiveSeedingTimeLimit.value());
}

if (!torrent->isPrivate())
{
Expand All @@ -502,48 +459,6 @@ void TorrentOptionsDialog::accept()
QDialog::accept();
}

qreal TorrentOptionsDialog::getRatio() 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_RATIO;

if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxRatio->isChecked())
return BitTorrent::Torrent::NO_RATIO_LIMIT;

return m_ui->spinRatioLimit->value();
}

int TorrentOptionsDialog::getSeedingTime() 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_SEEDING_TIME;

if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxTime->isChecked())
return BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT;

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([[maybe_unused]] const int index)
{
if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
Expand Down Expand Up @@ -619,31 +534,6 @@ void TorrentOptionsDialog::handleUseDownloadPathChanged()
m_ui->downloadPath->setSelectedPath(BitTorrent::Session::instance()->downloadPath());
}

void TorrentOptionsDialog::handleRatioTypeChanged()
{
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();
if (currentRadio && (currentRadio == m_previousRadio))
{
// Hack to deselect the currently selected radio button programmatically because Qt doesn't allow it in exclusive mode
m_ui->buttonGroup->setExclusive(false);
currentRadio->setChecked(false);
m_ui->buttonGroup->setExclusive(true);
}
m_previousRadio = m_ui->buttonGroup->checkedButton();
}

m_ui->checkMaxRatio->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->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()
{
m_ui->spinUploadLimit->setMinimum(0);
Expand Down
15 changes: 6 additions & 9 deletions src/gui/torrentoptionsdialog.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2024 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2020 thalieht
* Copyright (C) 2011 Christian Kandeler
* Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
Expand Down Expand Up @@ -30,6 +31,8 @@

#pragma once

#include <optional>

#include <QDialog>

#include "base/path.h"
Expand Down Expand Up @@ -68,13 +71,7 @@ private slots:
void handleUpSpeedLimitChanged();
void handleDownSpeedLimitChanged();

void handleRatioTypeChanged();

private:
qreal getRatio() const;
int getSeedingTime() const;
int getInactiveSeedingTime() const;

QVector<BitTorrent::TorrentID> m_torrentIDs;
Ui::TorrentOptionsDialog *m_ui = nullptr;
SettingValue<QSize> m_storeDialogSize;
Expand All @@ -87,9 +84,9 @@ private slots:
Path savePath;
Path downloadPath;
QString category;
qreal ratio;
int seedingTime;
int inactiveSeedingTime;
std::optional<qreal> ratio;
std::optional<int> seedingTime;
std::optional<int> inactiveSeedingTime;
int upSpeedLimit;
int downSpeedLimit;
Qt::CheckState autoTMM;
Expand Down
Loading

0 comments on commit 1702b6c

Please sign in to comment.