mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-29 05:48:47 +03:00
Merge pull request #15452 from thalieht/autoTMM
Move some options from transfer list's context menu into "Torrent options" dialog
This commit is contained in:
commit
b45248bf99
5 changed files with 294 additions and 107 deletions
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "torrentoptionsdialog.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "base/bittorrent/torrent.h"
|
||||
#include "base/global.h"
|
||||
#include "base/unicodestrings.h"
|
||||
#include "base/utils/fs.h"
|
||||
#include "ui_torrentoptionsdialog.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -59,13 +61,22 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
: QDialog {parent}
|
||||
, m_ui {new Ui::TorrentOptionsDialog}
|
||||
, m_storeDialogSize {SETTINGS_KEY("Size")}
|
||||
, m_currentCategoriesString {QString::fromLatin1("--%1--").arg(tr("Currently used categories"))}
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->savePath->setMode(FileSystemPathEdit::Mode::DirectorySave);
|
||||
m_ui->savePath->setDialogCaption(tr("Choose save path"));
|
||||
Q_ASSERT(!torrents.empty());
|
||||
|
||||
const auto *session = BitTorrent::Session::instance();
|
||||
bool allSameUpLimit = true, allSameDownLimit = true, allSameRatio = true, allSameSeedingTime = true
|
||||
, allTorrentsArePrivate = true, allSameDHT = true, allSamePEX = true, allSameLSD = true;
|
||||
, allTorrentsArePrivate = true, allSameDHT = true, allSamePEX = true, allSameLSD = true
|
||||
, allSameSequential = true, allSameFirstLastPieces = true, allSameAutoTMM = true, allSameSavePath = true;
|
||||
|
||||
const bool isFirstTorrentAutoTMMEnabled = torrents[0]->isAutoTMMEnabled();
|
||||
const QString firstTorrentSavePath = torrents[0]->savePath();
|
||||
const QString firstTorrentCategory = torrents[0]->category();
|
||||
|
||||
const int firstTorrentUpLimit = qMax(0, torrents[0]->uploadLimit());
|
||||
const int firstTorrentDownLimit = qMax(0, torrents[0]->downloadLimit());
|
||||
|
@ -76,11 +87,29 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
const bool isFirstTorrentDHTDisabled = torrents[0]->isDHTDisabled();
|
||||
const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled();
|
||||
const bool isFirstTorrentLSDDisabled = torrents[0]->isLSDDisabled();
|
||||
const bool isFirstTorrentSequentialEnabled = torrents[0]->isSequentialDownload();
|
||||
const bool isFirstTorrentFirstLastPiecesEnabled = torrents[0]->hasFirstLastPiecePriority();
|
||||
|
||||
m_torrentIDs.reserve(torrents.size());
|
||||
for (const BitTorrent::Torrent *torrent : torrents)
|
||||
{
|
||||
m_torrentIDs << torrent->id();
|
||||
|
||||
if (allSameAutoTMM)
|
||||
{
|
||||
if (torrent->isAutoTMMEnabled() != isFirstTorrentAutoTMMEnabled)
|
||||
allSameAutoTMM = false;
|
||||
}
|
||||
if (allSameSavePath)
|
||||
{
|
||||
if (torrent->savePath() != firstTorrentSavePath)
|
||||
allSameSavePath = false;
|
||||
}
|
||||
if (m_allSameCategory)
|
||||
{
|
||||
if (torrent->category() != firstTorrentCategory)
|
||||
m_allSameCategory = false;
|
||||
}
|
||||
if (allSameUpLimit)
|
||||
{
|
||||
if (qMax(0, torrent->uploadLimit()) != firstTorrentUpLimit)
|
||||
|
@ -109,27 +138,59 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
if (allSameDHT)
|
||||
{
|
||||
if (torrent->isDHTDisabled() != isFirstTorrentDHTDisabled)
|
||||
{
|
||||
m_ui->checkDisableDHT->setCheckState(Qt::PartiallyChecked);
|
||||
allSameDHT = false;
|
||||
}
|
||||
}
|
||||
if (allSamePEX)
|
||||
{
|
||||
if (torrent->isPEXDisabled() != isFirstTorrentPEXDisabled)
|
||||
{
|
||||
m_ui->checkDisablePEX->setCheckState(Qt::PartiallyChecked);
|
||||
allSamePEX = false;
|
||||
}
|
||||
}
|
||||
if (allSameLSD)
|
||||
{
|
||||
if (torrent->isLSDDisabled() != isFirstTorrentLSDDisabled)
|
||||
{
|
||||
m_ui->checkDisableLSD->setCheckState(Qt::PartiallyChecked);
|
||||
allSameLSD = false;
|
||||
}
|
||||
}
|
||||
if (allSameSequential)
|
||||
{
|
||||
if (torrent->isSequentialDownload() != isFirstTorrentSequentialEnabled)
|
||||
allSameSequential = false;
|
||||
}
|
||||
if (allSameFirstLastPieces)
|
||||
{
|
||||
if (torrent->hasFirstLastPiecePriority() != isFirstTorrentFirstLastPiecesEnabled)
|
||||
allSameFirstLastPieces = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allSameAutoTMM)
|
||||
m_ui->checkAutoTMM->setChecked(isFirstTorrentAutoTMMEnabled);
|
||||
else
|
||||
m_ui->checkAutoTMM->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
if (allSameSavePath)
|
||||
m_ui->savePath->setSelectedPath(firstTorrentSavePath);
|
||||
|
||||
if (!m_allSameCategory)
|
||||
{
|
||||
m_ui->comboCategory->addItem(m_currentCategoriesString);
|
||||
m_ui->comboCategory->clearEditText();
|
||||
m_ui->comboCategory->lineEdit()->setPlaceholderText(m_currentCategoriesString);
|
||||
}
|
||||
else if (!firstTorrentCategory.isEmpty())
|
||||
{
|
||||
m_ui->comboCategory->setCurrentText(firstTorrentCategory);
|
||||
m_ui->comboCategory->addItem(firstTorrentCategory);
|
||||
}
|
||||
m_ui->comboCategory->addItem(QString());
|
||||
|
||||
m_categories = session->categories().keys();
|
||||
std::sort(m_categories.begin(), m_categories.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||
for (const QString &category : asConst(m_categories))
|
||||
{
|
||||
if (m_allSameCategory && (category == firstTorrentCategory))
|
||||
continue;
|
||||
|
||||
m_ui->comboCategory->addItem(category);
|
||||
}
|
||||
|
||||
const bool isAltLimitEnabled = session->isAltGlobalSpeedLimitEnabled();
|
||||
|
@ -215,16 +276,23 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
? firstTorrentSeedingTime : session->globalMaxSeedingMinutes();
|
||||
m_ui->spinRatioLimit->setValue(maxRatio);
|
||||
m_ui->spinTimeLimit->setValue(maxSeedingTime);
|
||||
handleRatioTypeChanged();
|
||||
|
||||
if (!allTorrentsArePrivate)
|
||||
{
|
||||
if (m_ui->checkDisableDHT->checkState() != Qt::PartiallyChecked)
|
||||
if (allSameDHT)
|
||||
m_ui->checkDisableDHT->setChecked(isFirstTorrentDHTDisabled);
|
||||
if (m_ui->checkDisablePEX->checkState() != Qt::PartiallyChecked)
|
||||
else
|
||||
m_ui->checkDisableDHT->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
if (allSamePEX)
|
||||
m_ui->checkDisablePEX->setChecked(isFirstTorrentPEXDisabled);
|
||||
if (m_ui->checkDisableLSD->checkState() != Qt::PartiallyChecked)
|
||||
else
|
||||
m_ui->checkDisablePEX->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
if (allSameLSD)
|
||||
m_ui->checkDisableLSD->setChecked(isFirstTorrentLSDDisabled);
|
||||
else
|
||||
m_ui->checkDisableLSD->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -241,17 +309,39 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
m_ui->checkDisablePEX->setToolTip(privateTorrentsTooltip);
|
||||
m_ui->checkDisableLSD->setToolTip(privateTorrentsTooltip);
|
||||
|
||||
if (allSameSequential)
|
||||
m_ui->checkSequential->setChecked(isFirstTorrentSequentialEnabled);
|
||||
else
|
||||
m_ui->checkSequential->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
if (allSameFirstLastPieces)
|
||||
m_ui->checkFirstLastPieces->setChecked(isFirstTorrentFirstLastPiecesEnabled);
|
||||
else
|
||||
m_ui->checkFirstLastPieces->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
m_initialValues =
|
||||
{
|
||||
m_ui->savePath->selectedPath(),
|
||||
m_ui->comboCategory->currentText(),
|
||||
getRatio(),
|
||||
getSeedingTime(),
|
||||
m_ui->spinUploadLimit->value(),
|
||||
m_ui->spinDownloadLimit->value(),
|
||||
m_ui->checkAutoTMM->checkState(),
|
||||
m_ui->checkDisableDHT->checkState(),
|
||||
m_ui->checkDisablePEX->checkState(),
|
||||
m_ui->checkDisableLSD->checkState()
|
||||
m_ui->checkDisableLSD->checkState(),
|
||||
m_ui->checkSequential->checkState(),
|
||||
m_ui->checkFirstLastPieces->checkState()
|
||||
};
|
||||
|
||||
// Needs to be called after the initial values struct is initialized
|
||||
handleTMMChanged();
|
||||
handleRatioTypeChanged();
|
||||
|
||||
connect(m_ui->checkAutoTMM, &QCheckBox::clicked, this, &TorrentOptionsDialog::handleTMMChanged);
|
||||
connect(m_ui->comboCategory, &QComboBox::activated, this, &TorrentOptionsDialog::handleCategoryChanged);
|
||||
|
||||
// Sync up/down speed limit sliders with their corresponding spinboxes
|
||||
connect(m_ui->sliderUploadLimit, &QSlider::valueChanged, m_ui->spinUploadLimit, &QSpinBox::setValue);
|
||||
connect(m_ui->sliderDownloadLimit, &QSlider::valueChanged, m_ui->spinDownloadLimit, &QSpinBox::setValue);
|
||||
|
@ -282,12 +372,27 @@ void TorrentOptionsDialog::accept()
|
|||
return;
|
||||
}
|
||||
|
||||
const auto *session = BitTorrent::Session::instance();
|
||||
auto *session = BitTorrent::Session::instance();
|
||||
for (const BitTorrent::TorrentID &id : asConst(m_torrentIDs))
|
||||
{
|
||||
BitTorrent::Torrent *torrent = session->findTorrent(id);
|
||||
if (!torrent) continue;
|
||||
|
||||
const QString savePath = m_ui->savePath->selectedPath();
|
||||
if (m_initialValues.autoTMM != m_ui->checkAutoTMM->checkState())
|
||||
torrent->setAutoTMMEnabled(m_ui->checkAutoTMM->isChecked());
|
||||
if (!m_ui->checkAutoTMM->isChecked() && (m_initialValues.savePath != savePath))
|
||||
torrent->move(Utils::Fs::expandPathAbs(savePath));
|
||||
const QString category = m_ui->comboCategory->currentText();
|
||||
// index 0 is always the current category
|
||||
if ((m_initialValues.category != category) || (m_ui->comboCategory->currentIndex() != 0))
|
||||
{
|
||||
if (!m_categories.contains(category))
|
||||
session->addCategory(category);
|
||||
|
||||
torrent->setCategory(category);
|
||||
}
|
||||
|
||||
if (m_initialValues.upSpeedLimit != m_ui->spinUploadLimit->value())
|
||||
torrent->setUploadLimit(m_ui->spinUploadLimit->value() * 1024);
|
||||
if (m_initialValues.downSpeedLimit != m_ui->spinDownloadLimit->value())
|
||||
|
@ -310,6 +415,11 @@ void TorrentOptionsDialog::accept()
|
|||
if (m_initialValues.disableLSD != m_ui->checkDisableLSD->checkState())
|
||||
torrent->setLSDDisabled(m_ui->checkDisableLSD->isChecked());
|
||||
}
|
||||
|
||||
if (m_initialValues.sequential != m_ui->checkSequential->checkState())
|
||||
torrent->setSequentialDownload(m_ui->checkSequential->isChecked());
|
||||
if (m_initialValues.firstLastPieces != m_ui->checkFirstLastPieces->checkState())
|
||||
torrent->setFirstLastPiecePriority(m_ui->checkFirstLastPieces->isChecked());
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
|
@ -343,8 +453,80 @@ int TorrentOptionsDialog::getSeedingTime() const
|
|||
return m_ui->spinTimeLimit->value();
|
||||
}
|
||||
|
||||
void TorrentOptionsDialog::handleCategoryChanged(const int index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
|
||||
if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
|
||||
{
|
||||
if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
|
||||
{
|
||||
m_ui->savePath->setSelectedPath(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->comboCategory->currentText());
|
||||
m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(savePath));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
|
||||
{
|
||||
m_ui->comboCategory->clearEditText();
|
||||
m_ui->comboCategory->lineEdit()->setPlaceholderText(m_currentCategoriesString);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->comboCategory->lineEdit()->setPlaceholderText(QString());
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentOptionsDialog::handleTMMChanged()
|
||||
{
|
||||
if (m_ui->checkAutoTMM->checkState() == Qt::Unchecked)
|
||||
{
|
||||
m_ui->labelSavePath->setEnabled(true);
|
||||
m_ui->savePath->setEnabled(true);
|
||||
m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(m_initialValues.savePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->labelSavePath->setEnabled(false);
|
||||
m_ui->savePath->setEnabled(false);
|
||||
if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
|
||||
{
|
||||
if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
|
||||
{
|
||||
m_ui->savePath->setSelectedPath(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
const QString savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->comboCategory->currentText());
|
||||
m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(savePath));
|
||||
}
|
||||
}
|
||||
else // partially checked
|
||||
{
|
||||
m_ui->savePath->setSelectedPath(QString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentOptionsDialog::handleRatioTypeChanged()
|
||||
{
|
||||
if ((m_initialValues.ratio == MIXED_SHARE_LIMITS) || (m_initialValues.seedingTime == MIXED_SHARE_LIMITS))
|
||||
{
|
||||
QAbstractButton *currentRadio = m_ui->buttonGroup->checkedButton();
|
||||
if (currentRadio && (currentRadio == m_previousRadio))
|
||||
{
|
||||
// Hack to deselect the currently selected radio button programatically 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());
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
|
||||
#include "base/settingvalue.h"
|
||||
|
||||
class QAbstractButton;
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
class Torrent;
|
||||
|
@ -58,6 +60,9 @@ public slots:
|
|||
void accept() override;
|
||||
|
||||
private slots:
|
||||
void handleCategoryChanged(int index);
|
||||
void handleTMMChanged();
|
||||
|
||||
void handleUpSpeedLimitChanged();
|
||||
void handleDownSpeedLimitChanged();
|
||||
|
||||
|
@ -70,14 +75,23 @@ private:
|
|||
QVector<BitTorrent::TorrentID> m_torrentIDs;
|
||||
Ui::TorrentOptionsDialog *m_ui;
|
||||
SettingValue<QSize> m_storeDialogSize;
|
||||
QStringList m_categories;
|
||||
QString m_currentCategoriesString;
|
||||
bool m_allSameCategory = true;
|
||||
QAbstractButton *m_previousRadio = nullptr;
|
||||
struct
|
||||
{
|
||||
QString savePath;
|
||||
QString category;
|
||||
qreal ratio;
|
||||
int seedingTime;
|
||||
int upSpeedLimit;
|
||||
int downSpeedLimit;
|
||||
Qt::CheckState autoTMM;
|
||||
Qt::CheckState disableDHT;
|
||||
Qt::CheckState disablePEX;
|
||||
Qt::CheckState disableLSD;
|
||||
Qt::CheckState sequential;
|
||||
Qt::CheckState firstLastPieces;
|
||||
} m_initialValues;
|
||||
};
|
||||
|
|
|
@ -6,14 +6,71 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>390</width>
|
||||
<height>450</height>
|
||||
<width>450</width>
|
||||
<height>540</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Torrent Options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkAutoTMM">
|
||||
<property name="toolTip">
|
||||
<string>Automatic mode means that various torrent properties (e.g. save path) will be decided by the associated category</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automatic Torrent Management</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelSavePath">
|
||||
<property name="text">
|
||||
<string>Save path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="FileSystemPathLineEdit" name="savePath" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelCategory">
|
||||
<property name="text">
|
||||
<string>Category:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboCategory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAtTop</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
|
@ -187,6 +244,13 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkSequential">
|
||||
<property name="text">
|
||||
<string>Download in sequential order</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
@ -206,6 +270,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkFirstLastPieces">
|
||||
<property name="text">
|
||||
<string>Download first and last pieces first</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkDisableLSD">
|
||||
<property name="text">
|
||||
|
@ -237,6 +308,14 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>FileSystemPathLineEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/fspathedit.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
@ -328,21 +328,6 @@ QVector<BitTorrent::Torrent *> TransferListWidget::getVisibleTorrents() const
|
|||
return torrents;
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedTorrentsLocation()
|
||||
{
|
||||
const QVector<BitTorrent::Torrent *> torrents = getSelectedTorrents();
|
||||
if (torrents.isEmpty()) return;
|
||||
|
||||
const QString oldLocation = torrents[0]->savePath();
|
||||
const QString newLocation = QFileDialog::getExistingDirectory(this, tr("Choose save path"), oldLocation,
|
||||
QFileDialog::DontConfirmOverwrite | QFileDialog::ShowDirsOnly | QFileDialog::HideNameFilterDetails);
|
||||
if (newLocation.isEmpty() || !QDir(newLocation).exists()) return;
|
||||
|
||||
// Actually move storage
|
||||
for (BitTorrent::Torrent *const torrent : torrents)
|
||||
torrent->move(Utils::Fs::expandPathAbs(newLocation));
|
||||
}
|
||||
|
||||
void TransferListWidget::pauseAllTorrents()
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(BitTorrent::Session::instance()->torrents()))
|
||||
|
@ -659,18 +644,6 @@ void TransferListWidget::setSelectedTorrentsSuperSeeding(const bool enabled) con
|
|||
}
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedTorrentsSequentialDownload(const bool enabled) const
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
|
||||
torrent->setSequentialDownload(enabled);
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedFirstLastPiecePrio(const bool enabled) const
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
|
||||
torrent->setFirstLastPiecePriority(enabled);
|
||||
}
|
||||
|
||||
void TransferListWidget::setSelectedAutoTMMEnabled(const bool enabled) const
|
||||
{
|
||||
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
|
||||
|
@ -845,8 +818,6 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
connect(actionTopQueuePos, &QAction::triggered, this, &TransferListWidget::topQueuePosSelectedTorrents);
|
||||
auto *actionBottomQueuePos = new QAction(UIThemeManager::instance()->getIcon("go-bottom"), tr("Move to bottom", "i.e. Move to bottom of the queue"), listMenu);
|
||||
connect(actionBottomQueuePos, &QAction::triggered, this, &TransferListWidget::bottomQueuePosSelectedTorrents);
|
||||
auto *actionSetTorrentPath = new QAction(UIThemeManager::instance()->getIcon("inode-directory"), tr("Set location..."), listMenu);
|
||||
connect(actionSetTorrentPath, &QAction::triggered, this, &TransferListWidget::setSelectedTorrentsLocation);
|
||||
auto *actionForceRecheck = new QAction(UIThemeManager::instance()->getIcon("document-edit-verify"), tr("Force recheck"), listMenu);
|
||||
connect(actionForceRecheck, &QAction::triggered, this, &TransferListWidget::recheckSelectedTorrents);
|
||||
auto *actionForceReannounce = new QAction(UIThemeManager::instance()->getIcon("document-edit-verify"), tr("Force reannounce"), listMenu);
|
||||
|
@ -865,13 +836,6 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
connect(actionSuperSeedingMode, &QAction::triggered, this, &TransferListWidget::setSelectedTorrentsSuperSeeding);
|
||||
auto *actionRename = new QAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename..."), listMenu);
|
||||
connect(actionRename, &QAction::triggered, this, &TransferListWidget::renameSelectedTorrent);
|
||||
auto *actionSequentialDownload = new TriStateAction(tr("Download in sequential order"), listMenu);
|
||||
connect(actionSequentialDownload, &QAction::triggered, this, &TransferListWidget::setSelectedTorrentsSequentialDownload);
|
||||
auto *actionFirstLastPiecePrio = new TriStateAction(tr("Download first and last pieces first"), listMenu);
|
||||
connect(actionFirstLastPiecePrio, &QAction::triggered, this, &TransferListWidget::setSelectedFirstLastPiecePrio);
|
||||
auto *actionAutoTMM = new TriStateAction(tr("Automatic Torrent Management"), listMenu);
|
||||
actionAutoTMM->setToolTip(tr("Automatic mode means that various torrent properties(eg save path) will be decided by the associated category"));
|
||||
connect(actionAutoTMM, &QAction::triggered, this, &TransferListWidget::setSelectedAutoTMMEnabled);
|
||||
auto *actionEditTracker = new QAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Edit trackers..."), listMenu);
|
||||
connect(actionEditTracker, &QAction::triggered, this, &TransferListWidget::editTorrentTrackers);
|
||||
// End of actions
|
||||
|
@ -884,8 +848,6 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
bool sequentialDownloadMode = false, prioritizeFirstLast = false;
|
||||
bool oneHasMetadata = false, oneNotSeed = false;
|
||||
bool allSameCategory = true;
|
||||
bool allSameAutoTMM = true;
|
||||
bool firstAutoTMM = false;
|
||||
QString firstCategory;
|
||||
bool first = true;
|
||||
TagSet tagsInAny;
|
||||
|
@ -909,7 +871,6 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
|
||||
if (first)
|
||||
{
|
||||
firstAutoTMM = torrent->isAutoTMMEnabled();
|
||||
tagsInAll = torrentTags;
|
||||
}
|
||||
else
|
||||
|
@ -917,9 +878,6 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
tagsInAll.intersect(torrentTags);
|
||||
}
|
||||
|
||||
if (firstAutoTMM != torrent->isAutoTMMEnabled())
|
||||
allSameAutoTMM = false;
|
||||
|
||||
if (torrent->hasMetadata())
|
||||
oneHasMetadata = true;
|
||||
if (!torrent->isSeed())
|
||||
|
@ -979,7 +937,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
|
||||
if (oneHasMetadata && oneNotSeed && !allSameSequentialDownloadMode
|
||||
&& !allSamePrioFirstlast && !allSameSuperSeeding && !allSameCategory
|
||||
&& needsStart && needsForce && needsPause && needsPreview && !allSameAutoTMM
|
||||
&& needsStart && needsForce && needsPause && needsPreview
|
||||
&& hasInfohashV1 && hasInfohashV2)
|
||||
{
|
||||
break;
|
||||
|
@ -995,36 +953,10 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
listMenu->addSeparator();
|
||||
listMenu->addAction(actionDelete);
|
||||
listMenu->addSeparator();
|
||||
listMenu->addAction(actionSetTorrentPath);
|
||||
if (selectedIndexes.size() == 1)
|
||||
listMenu->addAction(actionRename);
|
||||
listMenu->addAction(actionEditTracker);
|
||||
|
||||
// Category Menu
|
||||
QStringList categories = BitTorrent::Session::instance()->categories().keys();
|
||||
std::sort(categories.begin(), categories.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||
|
||||
QMenu *categoryMenu = listMenu->addMenu(UIThemeManager::instance()->getIcon("view-categories"), tr("Category"));
|
||||
|
||||
categoryMenu->addAction(UIThemeManager::instance()->getIcon("list-add"), tr("New...", "New category...")
|
||||
, this, &TransferListWidget::askNewCategoryForSelection);
|
||||
categoryMenu->addAction(UIThemeManager::instance()->getIcon("edit-clear"), tr("Reset", "Reset category")
|
||||
, this, [this]() { setSelectionCategory(""); });
|
||||
categoryMenu->addSeparator();
|
||||
|
||||
for (const QString &category : asConst(categories))
|
||||
{
|
||||
const QString escapedCategory = QString(category).replace('&', "&&"); // avoid '&' becomes accelerator key
|
||||
QAction *cat = categoryMenu->addAction(UIThemeManager::instance()->getIcon("inode-directory"), escapedCategory
|
||||
, this, [this, category]() { setSelectionCategory(category); });
|
||||
|
||||
if (allSameCategory && (category == firstCategory))
|
||||
{
|
||||
cat->setCheckable(true);
|
||||
cat->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Tag Menu
|
||||
QStringList tags(BitTorrent::Session::instance()->tags().values());
|
||||
std::sort(tags.begin(), tags.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
|
||||
|
@ -1063,11 +995,6 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
tagsMenu->addAction(action);
|
||||
}
|
||||
|
||||
actionAutoTMM->setCheckState(allSameAutoTMM
|
||||
? (firstAutoTMM ? Qt::Checked : Qt::Unchecked)
|
||||
: Qt::PartiallyChecked);
|
||||
listMenu->addAction(actionAutoTMM);
|
||||
|
||||
listMenu->addSeparator();
|
||||
listMenu->addAction(actionTorrentOptions);
|
||||
if (!oneNotSeed && oneHasMetadata)
|
||||
|
@ -1085,19 +1012,7 @@ void TransferListWidget::displayListMenu(const QPoint &)
|
|||
addedPreviewAction = true;
|
||||
}
|
||||
if (oneNotSeed)
|
||||
{
|
||||
actionSequentialDownload->setCheckState(allSameSequentialDownloadMode
|
||||
? (sequentialDownloadMode ? Qt::Checked : Qt::Unchecked)
|
||||
: Qt::PartiallyChecked);
|
||||
listMenu->addAction(actionSequentialDownload);
|
||||
|
||||
actionFirstLastPiecePrio->setCheckState(allSamePrioFirstlast
|
||||
? (prioritizeFirstLast ? Qt::Checked : Qt::Unchecked)
|
||||
: Qt::PartiallyChecked);
|
||||
listMenu->addAction(actionFirstLastPiecePrio);
|
||||
|
||||
addedPreviewAction = true;
|
||||
}
|
||||
|
||||
if (addedPreviewAction)
|
||||
listMenu->addSeparator();
|
||||
|
|
|
@ -65,7 +65,6 @@ public slots:
|
|||
void addSelectionTag(const QString &tag);
|
||||
void removeSelectionTag(const QString &tag);
|
||||
void clearSelectionTags();
|
||||
void setSelectedTorrentsLocation();
|
||||
void pauseAllTorrents();
|
||||
void resumeAllTorrents();
|
||||
void startSelectedTorrents();
|
||||
|
@ -109,8 +108,6 @@ private slots:
|
|||
void displayListMenu(const QPoint &);
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex&) override;
|
||||
void setSelectedTorrentsSuperSeeding(bool enabled) const;
|
||||
void setSelectedTorrentsSequentialDownload(bool enabled) const;
|
||||
void setSelectedFirstLastPiecePrio(bool enabled) const;
|
||||
void setSelectedAutoTMMEnabled(bool enabled) const;
|
||||
void askNewCategoryForSelection();
|
||||
void saveSettings();
|
||||
|
|
Loading…
Reference in a new issue