Bump to 4.6.7
[qBittorrent.git] / src / gui / torrentoptionsdialog.cpp
bloba618453da842fb15872739cfcfe012023952fef5
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2020 thalieht
4 * Copyright (C) 2011 Christian Kandeler
5 * Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * In addition, as a special exception, the copyright holders give permission to
22 * link this program with the OpenSSL project's "OpenSSL" library (or with
23 * modified versions of it that use the same license as the "OpenSSL" library),
24 * and distribute the linked executables. You must obey the GNU General Public
25 * License in all respects for all of the code used other than "OpenSSL". If you
26 * modify file(s), you may extend this exception to your version of the file(s),
27 * but you are not obligated to do so. If you do not wish to do so, delete this
28 * exception statement from your version.
31 #include "torrentoptionsdialog.h"
33 #include <algorithm>
35 #include <QLineEdit>
36 #include <QMessageBox>
37 #include <QString>
39 #include "base/bittorrent/infohash.h"
40 #include "base/bittorrent/session.h"
41 #include "base/bittorrent/torrent.h"
42 #include "base/global.h"
43 #include "base/unicodestrings.h"
44 #include "base/utils/fs.h"
45 #include "ui_torrentoptionsdialog.h"
46 #include "utils.h"
48 #define SETTINGS_KEY(name) u"TorrentOptionsDialog/" name
50 namespace
52 const int MIXED_SHARE_LIMITS = -9;
54 void updateSliderValue(QSlider *slider, const int value)
56 if (value > slider->maximum())
57 slider->setMaximum(value);
58 slider->setValue(value);
62 TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTorrent::Torrent *> &torrents)
63 : QDialog {parent}
64 , m_ui {new Ui::TorrentOptionsDialog}
65 , m_storeDialogSize {SETTINGS_KEY(u"Size"_s)}
66 , m_currentCategoriesString {u"--%1--"_s.arg(tr("Currently used categories"))}
68 Q_ASSERT(!torrents.empty());
70 m_ui->setupUi(this);
72 connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
73 connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
75 m_ui->savePath->setMode(FileSystemPathEdit::Mode::DirectorySave);
76 m_ui->savePath->setDialogCaption(tr("Choose save path"));
77 m_ui->downloadPath->setMode(FileSystemPathEdit::Mode::DirectorySave);
78 m_ui->downloadPath->setDialogCaption(tr("Choose save path"));
80 const auto *session = BitTorrent::Session::instance();
81 bool allSameUpLimit = true;
82 bool allSameDownLimit = true;
83 bool allSameRatio = true;
84 bool allSameSeedingTime = true;
85 bool allSameInactiveSeedingTime = true;
86 bool allTorrentsArePrivate = true;
87 bool allSameDHT = true;
88 bool allSamePEX = true;
89 bool allSameLSD = true;
90 bool allSameSequential = true;
91 bool allSameFirstLastPieces = true;
92 bool allSameAutoTMM = true;
93 bool allSameSavePath = true;
94 bool allSameDownloadPath = true;
96 const bool isFirstTorrentAutoTMMEnabled = torrents[0]->isAutoTMMEnabled();
97 const Path firstTorrentSavePath = torrents[0]->savePath();
98 const Path firstTorrentDownloadPath = torrents[0]->downloadPath();
99 const QString firstTorrentCategory = torrents[0]->category();
101 const int firstTorrentUpLimit = std::max(0, torrents[0]->uploadLimit());
102 const int firstTorrentDownLimit = std::max(0, torrents[0]->downloadLimit());
104 const qreal firstTorrentRatio = torrents[0]->ratioLimit();
105 const int firstTorrentSeedingTime = torrents[0]->seedingTimeLimit();
106 const int firstTorrentInactiveSeedingTime = torrents[0]->inactiveSeedingTimeLimit();
108 const bool isFirstTorrentDHTDisabled = torrents[0]->isDHTDisabled();
109 const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled();
110 const bool isFirstTorrentLSDDisabled = torrents[0]->isLSDDisabled();
111 const bool isFirstTorrentSequentialEnabled = torrents[0]->isSequentialDownload();
112 const bool isFirstTorrentFirstLastPiecesEnabled = torrents[0]->hasFirstLastPiecePriority();
114 m_torrentIDs.reserve(torrents.size());
115 for (const BitTorrent::Torrent *torrent : torrents)
117 m_torrentIDs << torrent->id();
119 if (allSameAutoTMM)
121 if (torrent->isAutoTMMEnabled() != isFirstTorrentAutoTMMEnabled)
122 allSameAutoTMM = false;
124 if (allSameSavePath)
126 if (torrent->savePath() != firstTorrentSavePath)
127 allSameSavePath = false;
129 if (allSameDownloadPath)
131 if (torrent->downloadPath() != firstTorrentDownloadPath)
132 allSameDownloadPath = false;
134 if (m_allSameCategory)
136 if (torrent->category() != firstTorrentCategory)
137 m_allSameCategory = false;
139 if (allSameUpLimit)
141 if (std::max(0, torrent->uploadLimit()) != firstTorrentUpLimit)
142 allSameUpLimit = false;
144 if (allSameDownLimit)
146 if (std::max(0, torrent->downloadLimit()) != firstTorrentDownLimit)
147 allSameDownLimit = false;
149 if (allSameRatio)
151 if (torrent->ratioLimit() != firstTorrentRatio)
152 allSameRatio = false;
154 if (allSameSeedingTime)
156 if (torrent->seedingTimeLimit() != firstTorrentSeedingTime)
157 allSameSeedingTime = false;
159 if (allSameInactiveSeedingTime)
161 if (torrent->inactiveSeedingTimeLimit() != firstTorrentInactiveSeedingTime)
162 allSameInactiveSeedingTime = false;
164 if (allTorrentsArePrivate)
166 if (!torrent->isPrivate())
167 allTorrentsArePrivate = false;
169 if (allSameDHT)
171 if (torrent->isDHTDisabled() != isFirstTorrentDHTDisabled)
172 allSameDHT = false;
174 if (allSamePEX)
176 if (torrent->isPEXDisabled() != isFirstTorrentPEXDisabled)
177 allSamePEX = false;
179 if (allSameLSD)
181 if (torrent->isLSDDisabled() != isFirstTorrentLSDDisabled)
182 allSameLSD = false;
184 if (allSameSequential)
186 if (torrent->isSequentialDownload() != isFirstTorrentSequentialEnabled)
187 allSameSequential = false;
189 if (allSameFirstLastPieces)
191 if (torrent->hasFirstLastPiecePriority() != isFirstTorrentFirstLastPiecesEnabled)
192 allSameFirstLastPieces = false;
196 if (allSameAutoTMM)
197 m_ui->checkAutoTMM->setChecked(isFirstTorrentAutoTMMEnabled);
198 else
199 m_ui->checkAutoTMM->setCheckState(Qt::PartiallyChecked);
201 if (allSameSavePath)
202 m_ui->savePath->setSelectedPath(firstTorrentSavePath);
204 if (allSameDownloadPath)
206 m_ui->downloadPath->setSelectedPath(firstTorrentDownloadPath);
207 m_ui->checkUseDownloadPath->setChecked(!firstTorrentDownloadPath.isEmpty());
209 else
211 m_ui->checkUseDownloadPath->setCheckState(Qt::PartiallyChecked);
214 if (!m_allSameCategory)
216 m_ui->comboCategory->addItem(m_currentCategoriesString);
217 m_ui->comboCategory->clearEditText();
218 m_ui->comboCategory->lineEdit()->setPlaceholderText(m_currentCategoriesString);
220 else if (!firstTorrentCategory.isEmpty())
222 m_ui->comboCategory->setCurrentText(firstTorrentCategory);
223 m_ui->comboCategory->addItem(firstTorrentCategory);
225 m_ui->comboCategory->addItem(QString());
227 m_categories = session->categories();
228 std::sort(m_categories.begin(), m_categories.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
229 for (const QString &category : asConst(m_categories))
231 if (m_allSameCategory && (category == firstTorrentCategory))
232 continue;
234 m_ui->comboCategory->addItem(category);
237 const bool isAltLimitEnabled = session->isAltGlobalSpeedLimitEnabled();
238 const int globalUploadLimit = isAltLimitEnabled
239 ? (session->altGlobalUploadSpeedLimit() / 1024)
240 : (session->globalUploadSpeedLimit() / 1024);
241 const int globalDownloadLimit = isAltLimitEnabled
242 ? (session->altGlobalDownloadSpeedLimit() / 1024)
243 : (session->globalDownloadSpeedLimit() / 1024);
245 const int uploadVal = std::max(0, (firstTorrentUpLimit / 1024));
246 const int downloadVal = std::max(0, (firstTorrentDownLimit / 1024));
247 int maxUpload = (globalUploadLimit <= 0) ? 10000 : globalUploadLimit;
248 int maxDownload = (globalDownloadLimit <= 0) ? 10000 : globalDownloadLimit;
250 // This can happen for example if global rate limit is lower than torrent rate limit.
251 if (uploadVal > maxUpload)
252 maxUpload = uploadVal;
253 if (downloadVal > maxDownload)
254 maxDownload = downloadVal;
256 m_ui->sliderUploadLimit->setMaximum(maxUpload);
257 m_ui->sliderUploadLimit->setValue(allSameUpLimit ? uploadVal : (maxUpload / 2));
258 if (allSameUpLimit)
260 m_ui->spinUploadLimit->setValue(uploadVal);
262 else
264 m_ui->spinUploadLimit->setSpecialValueText(C_INEQUALITY);
265 m_ui->spinUploadLimit->setMinimum(-1);
266 m_ui->spinUploadLimit->setValue(-1);
267 connect(m_ui->spinUploadLimit, qOverload<int>(&QSpinBox::valueChanged)
268 , this, &TorrentOptionsDialog::handleUpSpeedLimitChanged);
271 m_ui->sliderDownloadLimit->setMaximum(maxDownload);
272 m_ui->sliderDownloadLimit->setValue(allSameDownLimit ? downloadVal : (maxDownload / 2));
273 if (allSameDownLimit)
275 m_ui->spinDownloadLimit->setValue(downloadVal);
277 else
279 m_ui->spinDownloadLimit->setSpecialValueText(C_INEQUALITY);
280 m_ui->spinDownloadLimit->setMinimum(-1);
281 m_ui->spinDownloadLimit->setValue(-1);
282 connect(m_ui->spinDownloadLimit, qOverload<int>(&QSpinBox::valueChanged)
283 , this, &TorrentOptionsDialog::handleDownSpeedLimitChanged);
286 const bool useGlobalValue = allSameRatio && allSameSeedingTime
287 && (firstTorrentRatio == BitTorrent::Torrent::USE_GLOBAL_RATIO)
288 && (firstTorrentSeedingTime == BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME)
289 && (firstTorrentInactiveSeedingTime == BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
291 if (!allSameRatio || !allSameSeedingTime || !allSameInactiveSeedingTime)
293 m_ui->radioUseGlobalShareLimits->setChecked(false);
294 m_ui->radioNoLimit->setChecked(false);
295 m_ui->radioTorrentLimit->setChecked(false);
297 else if (useGlobalValue)
299 m_ui->radioUseGlobalShareLimits->setChecked(true);
301 else if ((firstTorrentRatio == BitTorrent::Torrent::NO_RATIO_LIMIT)
302 && (firstTorrentSeedingTime == BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT)
303 && (firstTorrentInactiveSeedingTime == BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT))
305 m_ui->radioNoLimit->setChecked(true);
307 else
309 m_ui->radioTorrentLimit->setChecked(true);
310 if (firstTorrentRatio >= 0)
311 m_ui->checkMaxRatio->setChecked(true);
312 if (firstTorrentSeedingTime >= 0)
313 m_ui->checkMaxTime->setChecked(true);
314 if (firstTorrentInactiveSeedingTime >= 0)
315 m_ui->checkMaxInactiveTime->setChecked(true);
318 const qreal maxRatio = (allSameRatio && (firstTorrentRatio >= 0))
319 ? firstTorrentRatio : session->globalMaxRatio();
320 const int maxSeedingTime = (allSameSeedingTime && (firstTorrentSeedingTime >= 0))
321 ? firstTorrentSeedingTime : session->globalMaxSeedingMinutes();
322 const int maxInactiveSeedingTime = (allSameInactiveSeedingTime && (firstTorrentInactiveSeedingTime >= 0))
323 ? firstTorrentInactiveSeedingTime : session->globalMaxInactiveSeedingMinutes();
324 m_ui->spinRatioLimit->setValue(maxRatio);
325 m_ui->spinTimeLimit->setValue(maxSeedingTime);
326 m_ui->spinInactiveTimeLimit->setValue(maxInactiveSeedingTime);
328 if (!allTorrentsArePrivate)
330 if (allSameDHT)
331 m_ui->checkDisableDHT->setChecked(isFirstTorrentDHTDisabled);
332 else
333 m_ui->checkDisableDHT->setCheckState(Qt::PartiallyChecked);
335 if (allSamePEX)
336 m_ui->checkDisablePEX->setChecked(isFirstTorrentPEXDisabled);
337 else
338 m_ui->checkDisablePEX->setCheckState(Qt::PartiallyChecked);
340 if (allSameLSD)
341 m_ui->checkDisableLSD->setChecked(isFirstTorrentLSDDisabled);
342 else
343 m_ui->checkDisableLSD->setCheckState(Qt::PartiallyChecked);
345 else
347 m_ui->checkDisableDHT->setChecked(true);
348 m_ui->checkDisableDHT->setEnabled(false);
349 m_ui->checkDisablePEX->setChecked(true);
350 m_ui->checkDisablePEX->setEnabled(false);
351 m_ui->checkDisableLSD->setChecked(true);
352 m_ui->checkDisableLSD->setEnabled(false);
355 const QString privateTorrentsTooltip = tr("Not applicable to private torrents");
356 m_ui->checkDisableDHT->setToolTip(privateTorrentsTooltip);
357 m_ui->checkDisablePEX->setToolTip(privateTorrentsTooltip);
358 m_ui->checkDisableLSD->setToolTip(privateTorrentsTooltip);
360 if (allSameSequential)
361 m_ui->checkSequential->setChecked(isFirstTorrentSequentialEnabled);
362 else
363 m_ui->checkSequential->setCheckState(Qt::PartiallyChecked);
365 if (allSameFirstLastPieces)
366 m_ui->checkFirstLastPieces->setChecked(isFirstTorrentFirstLastPiecesEnabled);
367 else
368 m_ui->checkFirstLastPieces->setCheckState(Qt::PartiallyChecked);
370 m_initialValues =
372 m_ui->savePath->selectedPath(),
373 m_ui->downloadPath->selectedPath(),
374 m_ui->comboCategory->currentText(),
375 getRatio(),
376 getSeedingTime(),
377 getInactiveSeedingTime(),
378 m_ui->spinUploadLimit->value(),
379 m_ui->spinDownloadLimit->value(),
380 m_ui->checkAutoTMM->checkState(),
381 m_ui->checkUseDownloadPath->checkState(),
382 m_ui->checkDisableDHT->checkState(),
383 m_ui->checkDisablePEX->checkState(),
384 m_ui->checkDisableLSD->checkState(),
385 m_ui->checkSequential->checkState(),
386 m_ui->checkFirstLastPieces->checkState()
389 // Needs to be called after the initial values struct is initialized
390 handleTMMChanged();
391 handleUseDownloadPathChanged();
392 handleRatioTypeChanged();
394 connect(m_ui->checkAutoTMM, &QCheckBox::clicked, this, &TorrentOptionsDialog::handleTMMChanged);
395 connect(m_ui->checkUseDownloadPath, &QCheckBox::clicked, this, &TorrentOptionsDialog::handleUseDownloadPathChanged);
396 connect(m_ui->comboCategory, &QComboBox::activated, this, &TorrentOptionsDialog::handleCategoryChanged);
398 // Sync up/down speed limit sliders with their corresponding spinboxes
399 connect(m_ui->sliderUploadLimit, &QSlider::valueChanged, m_ui->spinUploadLimit, &QSpinBox::setValue);
400 connect(m_ui->sliderDownloadLimit, &QSlider::valueChanged, m_ui->spinDownloadLimit, &QSpinBox::setValue);
401 connect(m_ui->spinUploadLimit, qOverload<int>(&QSpinBox::valueChanged)
402 , this, [this](const int value) { updateSliderValue(m_ui->sliderUploadLimit, value); });
403 connect(m_ui->spinDownloadLimit, qOverload<int>(&QSpinBox::valueChanged)
404 , this, [this](const int value) { updateSliderValue(m_ui->sliderDownloadLimit, value); });
406 connect(m_ui->checkMaxRatio, &QCheckBox::toggled, m_ui->spinRatioLimit, &QWidget::setEnabled);
407 connect(m_ui->checkMaxTime, &QCheckBox::toggled, m_ui->spinTimeLimit, &QWidget::setEnabled);
408 connect(m_ui->checkMaxInactiveTime, &QCheckBox::toggled, m_ui->spinInactiveTimeLimit, &QSpinBox::setEnabled);
410 connect(m_ui->buttonGroup, &QButtonGroup::idClicked, this, &TorrentOptionsDialog::handleRatioTypeChanged);
412 if (const QSize dialogSize = m_storeDialogSize; dialogSize.isValid())
413 resize(dialogSize);
416 TorrentOptionsDialog::~TorrentOptionsDialog()
418 m_storeDialogSize = size();
419 delete m_ui;
422 void TorrentOptionsDialog::accept()
424 if (m_ui->radioTorrentLimit->isChecked() && !m_ui->checkMaxRatio->isChecked()
425 && !m_ui->checkMaxTime->isChecked() && !m_ui->checkMaxInactiveTime->isChecked())
427 QMessageBox::critical(this, tr("No share limit method selected"), tr("Please select a limit method first"));
428 return;
431 auto *session = BitTorrent::Session::instance();
432 for (const BitTorrent::TorrentID &id : asConst(m_torrentIDs))
434 BitTorrent::Torrent *torrent = session->getTorrent(id);
435 if (!torrent) continue;
437 if (m_initialValues.autoTMM != m_ui->checkAutoTMM->checkState())
438 torrent->setAutoTMMEnabled(m_ui->checkAutoTMM->isChecked());
440 if (m_ui->checkAutoTMM->checkState() == Qt::Unchecked)
442 const Path savePath = m_ui->savePath->selectedPath();
443 if (m_initialValues.savePath != savePath)
444 torrent->setSavePath(savePath);
446 const Qt::CheckState useDownloadPathState = m_ui->checkUseDownloadPath->checkState();
447 if (useDownloadPathState == Qt::Checked)
449 const Path downloadPath = m_ui->downloadPath->selectedPath();
450 if (m_initialValues.downloadPath != downloadPath)
451 torrent->setDownloadPath(downloadPath);
453 else if (useDownloadPathState == Qt::Unchecked)
455 torrent->setDownloadPath({});
459 const QString category = m_ui->comboCategory->currentText();
460 // index 0 is always the current category
461 if ((m_initialValues.category != category) || (m_ui->comboCategory->currentIndex() != 0))
463 if (!m_categories.contains(category))
464 session->addCategory(category);
466 torrent->setCategory(category);
469 if (m_initialValues.upSpeedLimit != m_ui->spinUploadLimit->value())
470 torrent->setUploadLimit(m_ui->spinUploadLimit->value() * 1024);
471 if (m_initialValues.downSpeedLimit != m_ui->spinDownloadLimit->value())
472 torrent->setDownloadLimit(m_ui->spinDownloadLimit->value() * 1024);
474 const qreal ratioLimit = getRatio();
475 if (m_initialValues.ratio != ratioLimit)
476 torrent->setRatioLimit(ratioLimit);
478 const int seedingTimeLimit = getSeedingTime();
479 if (m_initialValues.seedingTime != seedingTimeLimit)
480 torrent->setSeedingTimeLimit(seedingTimeLimit);
482 const int inactiveSeedingTimeLimit = getInactiveSeedingTime();
483 if (m_initialValues.inactiveSeedingTime != inactiveSeedingTimeLimit)
484 torrent->setInactiveSeedingTimeLimit(inactiveSeedingTimeLimit);
486 if (!torrent->isPrivate())
488 if (m_initialValues.disableDHT != m_ui->checkDisableDHT->checkState())
489 torrent->setDHTDisabled(m_ui->checkDisableDHT->isChecked());
490 if (m_initialValues.disablePEX != m_ui->checkDisablePEX->checkState())
491 torrent->setPEXDisabled(m_ui->checkDisablePEX->isChecked());
492 if (m_initialValues.disableLSD != m_ui->checkDisableLSD->checkState())
493 torrent->setLSDDisabled(m_ui->checkDisableLSD->isChecked());
496 if (m_initialValues.sequential != m_ui->checkSequential->checkState())
497 torrent->setSequentialDownload(m_ui->checkSequential->isChecked());
498 if (m_initialValues.firstLastPieces != m_ui->checkFirstLastPieces->checkState())
499 torrent->setFirstLastPiecePriority(m_ui->checkFirstLastPieces->isChecked());
502 QDialog::accept();
505 qreal TorrentOptionsDialog::getRatio() const
507 if (m_ui->buttonGroup->checkedId() == -1) // No radio button is selected
508 return MIXED_SHARE_LIMITS;
510 if (m_ui->radioUseGlobalShareLimits->isChecked())
511 return BitTorrent::Torrent::USE_GLOBAL_RATIO;
513 if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxRatio->isChecked())
514 return BitTorrent::Torrent::NO_RATIO_LIMIT;
516 return m_ui->spinRatioLimit->value();
519 int TorrentOptionsDialog::getSeedingTime() const
521 if (m_ui->buttonGroup->checkedId() == -1) // No radio button is selected
522 return MIXED_SHARE_LIMITS;
524 if (m_ui->radioUseGlobalShareLimits->isChecked())
525 return BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME;
527 if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxTime->isChecked())
528 return BitTorrent::Torrent::NO_SEEDING_TIME_LIMIT;
530 return m_ui->spinTimeLimit->value();
533 int TorrentOptionsDialog::getInactiveSeedingTime() const
535 if (m_ui->buttonGroup->checkedId() == -1) // No radio button is selected
536 return MIXED_SHARE_LIMITS;
538 if (m_ui->radioUseGlobalShareLimits->isChecked())
539 return BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
541 if (m_ui->radioNoLimit->isChecked() || !m_ui->checkMaxInactiveTime->isChecked())
542 return BitTorrent::Torrent::NO_INACTIVE_SEEDING_TIME_LIMIT;
544 return m_ui->spinInactiveTimeLimit->value();
547 void TorrentOptionsDialog::handleCategoryChanged(const int index)
549 Q_UNUSED(index);
551 if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
553 if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
555 m_ui->savePath->setSelectedPath({});
557 else
559 const Path savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->comboCategory->currentText());
560 m_ui->savePath->setSelectedPath(savePath);
561 const Path downloadPath = BitTorrent::Session::instance()->categoryDownloadPath(m_ui->comboCategory->currentText());
562 m_ui->downloadPath->setSelectedPath(downloadPath);
563 m_ui->checkUseDownloadPath->setChecked(!downloadPath.isEmpty());
567 if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
569 m_ui->comboCategory->clearEditText();
570 m_ui->comboCategory->lineEdit()->setPlaceholderText(m_currentCategoriesString);
572 else
574 m_ui->comboCategory->lineEdit()->setPlaceholderText(QString());
578 void TorrentOptionsDialog::handleTMMChanged()
580 if (m_ui->checkAutoTMM->checkState() == Qt::Unchecked)
582 m_ui->groupBoxSavePath->setEnabled(true);
583 m_ui->savePath->setSelectedPath(m_initialValues.savePath);
584 m_ui->downloadPath->setSelectedPath(m_initialValues.downloadPath);
585 m_ui->checkUseDownloadPath->setCheckState(m_initialValues.useDownloadPath);
587 else
589 m_ui->groupBoxSavePath->setEnabled(false);
590 if (m_ui->checkAutoTMM->checkState() == Qt::Checked)
592 if (!m_allSameCategory && (m_ui->comboCategory->currentIndex() == 0))
594 m_ui->savePath->setSelectedPath({});
595 m_ui->downloadPath->setSelectedPath({});
596 m_ui->checkUseDownloadPath->setCheckState(Qt::PartiallyChecked);
598 else
600 const Path savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->comboCategory->currentText());
601 m_ui->savePath->setSelectedPath(savePath);
602 const Path downloadPath = BitTorrent::Session::instance()->categoryDownloadPath(m_ui->comboCategory->currentText());
603 m_ui->downloadPath->setSelectedPath(downloadPath);
604 m_ui->checkUseDownloadPath->setChecked(!downloadPath.isEmpty());
607 else // partially checked
609 m_ui->savePath->setSelectedPath({});
610 m_ui->downloadPath->setSelectedPath({});
611 m_ui->checkUseDownloadPath->setCheckState(Qt::PartiallyChecked);
616 void TorrentOptionsDialog::handleUseDownloadPathChanged()
618 const bool isChecked = m_ui->checkUseDownloadPath->checkState() == Qt::Checked;
619 m_ui->downloadPath->setEnabled(isChecked);
620 if (isChecked && m_ui->downloadPath->selectedPath().isEmpty())
621 m_ui->downloadPath->setSelectedPath(BitTorrent::Session::instance()->downloadPath());
624 void TorrentOptionsDialog::handleRatioTypeChanged()
626 if ((m_initialValues.ratio == MIXED_SHARE_LIMITS) || (m_initialValues.seedingTime == MIXED_SHARE_LIMITS)
627 || (m_initialValues.inactiveSeedingTime == MIXED_SHARE_LIMITS))
629 QAbstractButton *currentRadio = m_ui->buttonGroup->checkedButton();
630 if (currentRadio && (currentRadio == m_previousRadio))
632 // Hack to deselect the currently selected radio button programmatically because Qt doesn't allow it in exclusive mode
633 m_ui->buttonGroup->setExclusive(false);
634 currentRadio->setChecked(false);
635 m_ui->buttonGroup->setExclusive(true);
637 m_previousRadio = m_ui->buttonGroup->checkedButton();
640 m_ui->checkMaxRatio->setEnabled(m_ui->radioTorrentLimit->isChecked());
641 m_ui->checkMaxTime->setEnabled(m_ui->radioTorrentLimit->isChecked());
642 m_ui->checkMaxInactiveTime->setEnabled(m_ui->radioTorrentLimit->isChecked());
644 m_ui->spinRatioLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxRatio->isChecked());
645 m_ui->spinTimeLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxTime->isChecked());
646 m_ui->spinInactiveTimeLimit->setEnabled(m_ui->radioTorrentLimit->isChecked() && m_ui->checkMaxInactiveTime->isChecked());
649 void TorrentOptionsDialog::handleUpSpeedLimitChanged()
651 m_ui->spinUploadLimit->setMinimum(0);
652 m_ui->spinUploadLimit->setSpecialValueText(C_INFINITY);
653 disconnect(m_ui->spinUploadLimit, qOverload<int>(&QSpinBox::valueChanged)
654 , this, &TorrentOptionsDialog::handleUpSpeedLimitChanged);
657 void TorrentOptionsDialog::handleDownSpeedLimitChanged()
659 m_ui->spinDownloadLimit->setMinimum(0);
660 m_ui->spinDownloadLimit->setSpecialValueText(C_INFINITY);
661 disconnect(m_ui->spinDownloadLimit, qOverload<int>(&QSpinBox::valueChanged)
662 , this, &TorrentOptionsDialog::handleDownSpeedLimitChanged);