diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 663cb29fe..1303c4d58 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2022 Vladimir Golovnev + * Copyright (C) 2015-2023 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -170,6 +170,9 @@ namespace BitTorrent virtual bool useCategoryPathsInManualMode() const = 0; virtual void setUseCategoryPathsInManualMode(bool value) = 0; + virtual Path suggestedSavePath(const QString &categoryName, std::optional useAutoTMM) const = 0; + virtual Path suggestedDownloadPath(const QString &categoryName, std::optional useAutoTMM) const = 0; + static bool isValidTag(const QString &tag); virtual QSet tags() const = 0; virtual bool hasTag(const QString &tag) const = 0; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 0cf91c426..80ee809ea 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -759,11 +759,13 @@ void SessionImpl::setFinishedTorrentExportDirectory(const Path &path) Path SessionImpl::savePath() const { + // TODO: Make sure it is always non-empty return m_savePath; } Path SessionImpl::downloadPath() const { + // TODO: Make sure it is always non-empty return m_downloadPath; } @@ -943,6 +945,21 @@ void SessionImpl::setUseCategoryPathsInManualMode(const bool value) m_useCategoryPathsInManualMode = value; } +Path SessionImpl::suggestedSavePath(const QString &categoryName, std::optional useAutoTMM) const +{ + const bool useCategoryPaths = useAutoTMM.value_or(!isAutoTMMDisabledByDefault()) || useCategoryPathsInManualMode(); + const auto path = (useCategoryPaths ? categorySavePath(categoryName) : savePath()); + return path; +} + +Path SessionImpl::suggestedDownloadPath(const QString &categoryName, std::optional useAutoTMM) const +{ + const bool useCategoryPaths = useAutoTMM.value_or(!isAutoTMMDisabledByDefault()) || useCategoryPathsInManualMode(); + const auto categoryDownloadPath = this->categoryDownloadPath(categoryName); + const auto path = ((useCategoryPaths && !categoryDownloadPath.isEmpty()) ? categoryDownloadPath : downloadPath()); + return path; +} + QSet SessionImpl::tags() const { return m_tags; @@ -2576,61 +2593,39 @@ LoadTorrentParams SessionImpl::initLoadTorrentParams(const AddTorrentParams &add else loadTorrentParams.category = category; + const auto defaultSavePath = suggestedSavePath(loadTorrentParams.category, addTorrentParams.useAutoTMM); + const auto defaultDownloadPath = suggestedDownloadPath(loadTorrentParams.category, addTorrentParams.useAutoTMM); + + loadTorrentParams.useAutoTMM = addTorrentParams.useAutoTMM.value_or(!isAutoTMMDisabledByDefault()); + if (!addTorrentParams.useAutoTMM.has_value()) { // Default TMM settings - loadTorrentParams.useAutoTMM = !isAutoTMMDisabledByDefault(); - if (!loadTorrentParams.useAutoTMM) { - const bool useCategoryPaths = useCategoryPathsInManualMode(); - const Path categorySavePath = this->categorySavePath(loadTorrentParams.category); - Q_ASSERT(!categorySavePath.isEmpty()); - loadTorrentParams.savePath = (useCategoryPaths && Q_LIKELY(!categorySavePath.isEmpty())) - ? categorySavePath : savePath(); - + loadTorrentParams.savePath = defaultSavePath; if (isDownloadPathEnabled()) - { - const Path categoryDownloadPath = this->categoryDownloadPath(loadTorrentParams.category); - loadTorrentParams.downloadPath = (useCategoryPaths && !categoryDownloadPath.isEmpty()) - ? categoryDownloadPath : downloadPath(); - } + loadTorrentParams.downloadPath = (!defaultDownloadPath.isEmpty() ? defaultDownloadPath : downloadPath()); } } else { // Overridden TMM settings - loadTorrentParams.useAutoTMM = addTorrentParams.useAutoTMM.value(); - if (!loadTorrentParams.useAutoTMM) { if (addTorrentParams.savePath.isAbsolute()) - { loadTorrentParams.savePath = addTorrentParams.savePath; - } else - { - const bool useCategoryPaths = useCategoryPathsInManualMode(); - const Path categorySavePath = this->categorySavePath(loadTorrentParams.category); - Q_ASSERT(!categorySavePath.isEmpty()); - const Path basePath = (useCategoryPaths && Q_LIKELY(!categorySavePath.isEmpty())) - ? categorySavePath : savePath(); - loadTorrentParams.savePath = basePath / addTorrentParams.savePath; - } + loadTorrentParams.savePath = defaultSavePath / addTorrentParams.savePath; if (!addTorrentParams.useDownloadPath.has_value()) { // Default "Download path" settings if (isDownloadPathEnabled()) - { - const bool useCategoryPaths = useCategoryPathsInManualMode(); - const Path categoryDownloadPath = this->categoryDownloadPath(loadTorrentParams.category); - loadTorrentParams.downloadPath = (useCategoryPaths && !categoryDownloadPath.isEmpty()) - ? categoryDownloadPath : downloadPath(); - } + loadTorrentParams.downloadPath = (!defaultDownloadPath.isEmpty() ? defaultDownloadPath : downloadPath()); } else if (addTorrentParams.useDownloadPath.value()) { @@ -2642,10 +2637,7 @@ LoadTorrentParams SessionImpl::initLoadTorrentParams(const AddTorrentParams &add } else { - const bool useCategoryPaths = useCategoryPathsInManualMode(); - const Path categoryDownloadPath = this->categoryDownloadPath(loadTorrentParams.category); - const Path basePath = (useCategoryPaths && !categoryDownloadPath.isEmpty()) - ? categoryDownloadPath : downloadPath(); + const Path basePath = (!defaultDownloadPath.isEmpty() ? defaultDownloadPath : downloadPath()); loadTorrentParams.downloadPath = basePath / addTorrentParams.downloadPath; } } diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 449a7f44e..b2b93cb8d 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2022 Vladimir Golovnev + * Copyright (C) 2015-2023 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -160,6 +160,9 @@ namespace BitTorrent bool useCategoryPathsInManualMode() const override; void setUseCategoryPathsInManualMode(bool value) override; + Path suggestedSavePath(const QString &categoryName, std::optional useAutoTMM) const override; + Path suggestedDownloadPath(const QString &categoryName, std::optional useAutoTMM) const override; + QSet tags() const override; bool hasTag(const QString &tag) const override; bool addTag(const QString &tag) override; diff --git a/src/gui/addtorrentparamswidget.cpp b/src/gui/addtorrentparamswidget.cpp index 224b36cbe..0d83701d9 100644 --- a/src/gui/addtorrentparamswidget.cpp +++ b/src/gui/addtorrentparamswidget.cpp @@ -38,6 +38,18 @@ #include "torrenttagsdialog.h" #include "ui_addtorrentparamswidget.h" +namespace +{ + std::optional toOptionalBool(const QVariant &data) + { + if (!data.isValid()) + return std::nullopt; + + Q_ASSERT(data.userType() == QMetaType::Bool); + return data.toBool(); + } +} + AddTorrentParamsWidget::AddTorrentParamsWidget(BitTorrent::AddTorrentParams addTorrentParams, QWidget *parent) : QWidget(parent) , m_ui {new Ui::AddTorrentParamsWidget} @@ -47,7 +59,6 @@ AddTorrentParamsWidget::AddTorrentParamsWidget(BitTorrent::AddTorrentParams addT m_ui->savePathEdit->setMode(FileSystemPathEdit::Mode::DirectorySave); m_ui->savePathEdit->setDialogCaption(tr("Choose save path")); - m_ui->savePathEdit->setPlaceholder(Path(u"Default"_qs)); m_ui->downloadPathEdit->setMode(FileSystemPathEdit::Mode::DirectorySave); m_ui->downloadPathEdit->setDialogCaption(tr("Choose save path")); @@ -125,11 +136,7 @@ void AddTorrentParamsWidget::populate() ? m_ui->comboTTM->findData(*m_addTorrentParams.useAutoTMM) : 0); connect(m_ui->comboTTM, &QComboBox::currentIndexChanged, this, [this] { - const QVariant data = m_ui->comboTTM->currentData(); - if (!data.isValid()) - m_addTorrentParams.useAutoTMM = std::nullopt; - else - m_addTorrentParams.useAutoTMM = data.toBool(); + m_addTorrentParams.useAutoTMM = toOptionalBool(m_ui->comboTTM->currentData()); populateSavePathOptions(); }); @@ -153,9 +160,13 @@ void AddTorrentParamsWidget::populate() const auto *btSession = BitTorrent::Session::instance(); const bool useAutoTMM = m_addTorrentParams.useAutoTMM.value_or(!btSession->isAutoTMMDisabledByDefault()); if (useAutoTMM) - loadCategorySavePathOptions(); - else - loadCustomSavePathOptions(); + { + const auto downloadPathOption = btSession->categoryOptions(m_addTorrentParams.category).downloadPath; + m_ui->useDownloadPathComboBox->setCurrentIndex(downloadPathOption.has_value() + ? m_ui->useDownloadPathComboBox->findData(downloadPathOption->enabled) : 0); + } + + populateDefaultPaths(); }); m_ui->savePathEdit->disconnect(this); @@ -174,13 +185,9 @@ void AddTorrentParamsWidget::populate() }); connect(m_ui->useDownloadPathComboBox, &QComboBox::currentIndexChanged, this, [this] { - const QVariant data = m_ui->useDownloadPathComboBox->currentData(); - if (!data.isValid()) - m_addTorrentParams.useDownloadPath = std::nullopt; - else - m_addTorrentParams.useDownloadPath = data.toBool(); + m_addTorrentParams.useDownloadPath = toOptionalBool(m_ui->useDownloadPathComboBox->currentData()); - populateDownloadPathEdit(); + loadCustomDownloadPath(); }); m_ui->contentLayoutComboBox->disconnect(this); @@ -243,48 +250,20 @@ void AddTorrentParamsWidget::populate() void AddTorrentParamsWidget::loadCustomSavePathOptions() { - const auto *btSession = BitTorrent::Session::instance(); - const bool useCategoryPaths = btSession->useCategoryPathsInManualMode(); + [[maybe_unused]] const auto *btSession = BitTorrent::Session::instance(); + Q_ASSERT(!m_addTorrentParams.useAutoTMM.value_or(!btSession->isAutoTMMDisabledByDefault())); - const Path categorySavePath = btSession->categorySavePath(m_addTorrentParams.category); - const Path defaultSavePath = (useCategoryPaths && !categorySavePath.isEmpty()) - ? categorySavePath : btSession->savePath(); - m_ui->savePathEdit->setPlaceholder(defaultSavePath); m_ui->savePathEdit->setSelectedPath(m_addTorrentParams.savePath); m_ui->useDownloadPathComboBox->setCurrentIndex(m_addTorrentParams.useDownloadPath ? m_ui->useDownloadPathComboBox->findData(*m_addTorrentParams.useDownloadPath) : 0); - populateDownloadPathEdit(); + loadCustomDownloadPath(); } -void AddTorrentParamsWidget::loadCategorySavePathOptions() +void AddTorrentParamsWidget::loadCustomDownloadPath() { - const auto *btSession = BitTorrent::Session::instance(); - - const Path savePath = btSession->categorySavePath(m_addTorrentParams.category); - m_ui->savePathEdit->setPlaceholder(savePath); - - const Path downloadPath = btSession->categoryDownloadPath(m_addTorrentParams.category); - m_ui->downloadPathEdit->setPlaceholder(downloadPath); - - const bool useAutoTMM = m_addTorrentParams.useAutoTMM.value_or(!btSession->isAutoTMMDisabledByDefault()); - if (useAutoTMM) - { - const auto downloadPathOption = btSession->categoryOptions(m_addTorrentParams.category).downloadPath; - m_ui->useDownloadPathComboBox->setCurrentIndex(downloadPathOption.has_value() - ? m_ui->useDownloadPathComboBox->findData(downloadPathOption->enabled) : 0); - } -} - -void AddTorrentParamsWidget::populateDownloadPathEdit() -{ - const auto *btSession = BitTorrent::Session::instance(); - const bool useCategoryPaths = btSession->useCategoryPathsInManualMode(); - - const Path categoryDownloadPath = btSession->categoryDownloadPath(m_addTorrentParams.category); - const Path defaultDownloadPath = (useCategoryPaths && !categoryDownloadPath.isEmpty()) - ? categoryDownloadPath : btSession->downloadPath(); + populateDefaultDownloadPath(); if (!m_addTorrentParams.useDownloadPath.has_value()) { @@ -293,9 +272,6 @@ void AddTorrentParamsWidget::populateDownloadPathEdit() m_ui->downloadPathEdit->setEnabled(false); m_ui->downloadPathEdit->blockSignals(true); m_ui->downloadPathEdit->setSelectedPath(Path()); - - const bool useDownloadPath = btSession->isDownloadPathEnabled(); - m_ui->downloadPathEdit->setPlaceholder(useDownloadPath ? defaultDownloadPath : Path()); } else { @@ -304,7 +280,6 @@ void AddTorrentParamsWidget::populateDownloadPathEdit() const bool useDownloadPath = m_addTorrentParams.useDownloadPath.value(); if (useDownloadPath) { - m_ui->downloadPathEdit->setPlaceholder(defaultDownloadPath); m_ui->downloadPathEdit->setSelectedPath(m_addTorrentParams.downloadPath); m_ui->downloadPathEdit->blockSignals(false); @@ -315,12 +290,49 @@ void AddTorrentParamsWidget::populateDownloadPathEdit() m_ui->downloadPathEdit->setEnabled(false); m_ui->downloadPathEdit->blockSignals(true); - m_ui->downloadPathEdit->setPlaceholder(Path()); m_ui->downloadPathEdit->setSelectedPath(Path()); } } } +void AddTorrentParamsWidget::loadCategorySavePathOptions() +{ + const auto *btSession = BitTorrent::Session::instance(); + Q_ASSERT(m_addTorrentParams.useAutoTMM.value_or(!btSession->isAutoTMMDisabledByDefault())); + + const auto downloadPathOption = btSession->categoryOptions(m_addTorrentParams.category).downloadPath; + m_ui->useDownloadPathComboBox->setCurrentIndex(downloadPathOption.has_value() + ? m_ui->useDownloadPathComboBox->findData(downloadPathOption->enabled) : 0); +} + +void AddTorrentParamsWidget::populateDefaultPaths() +{ + const auto *btSession = BitTorrent::Session::instance(); + + const Path defaultSavePath = btSession->suggestedSavePath( + m_ui->categoryComboBox->currentText(), toOptionalBool(m_ui->comboTTM->currentData())); + m_ui->savePathEdit->setPlaceholder(defaultSavePath); + + populateDefaultDownloadPath(); +} + +void AddTorrentParamsWidget::populateDefaultDownloadPath() +{ + const auto *btSession = BitTorrent::Session::instance(); + + const std::optional useDownloadPath = toOptionalBool(m_ui->useDownloadPathComboBox->currentData()); + if (useDownloadPath.value_or(btSession->isDownloadPathEnabled())) + { + const Path defaultDownloadPath = btSession->suggestedDownloadPath( + m_ui->categoryComboBox->currentText(), toOptionalBool(m_ui->comboTTM->currentData())); + m_ui->downloadPathEdit->setPlaceholder(defaultDownloadPath); + } + else + { + m_ui->downloadPathEdit->setPlaceholder(Path()); + } +} + void AddTorrentParamsWidget::populateSavePathOptions() { if (!m_addTorrentParams.useAutoTMM.has_value()) @@ -328,6 +340,7 @@ void AddTorrentParamsWidget::populateSavePathOptions() // Default TMM settings m_ui->groupBoxSavePath->setEnabled(false); + m_ui->defaultsNoteLabel->setVisible(true); m_ui->savePathEdit->blockSignals(true); m_ui->savePathEdit->setSelectedPath(Path()); m_ui->downloadPathEdit->blockSignals(true); @@ -343,27 +356,8 @@ void AddTorrentParamsWidget::populateSavePathOptions() } else { - const bool useCategoryPaths = btSession->useCategoryPathsInManualMode(); - - const Path categorySavePath = btSession->categorySavePath(m_addTorrentParams.category); - Q_ASSERT(!categorySavePath.isEmpty()); - const Path defaultSavePath = (useCategoryPaths && Q_LIKELY(!categorySavePath.isEmpty())) - ? categorySavePath : btSession->savePath(); - m_ui->savePathEdit->setPlaceholder(defaultSavePath); - - const bool useDownloadPath = btSession->isDownloadPathEnabled(); - m_ui->useDownloadPathComboBox->setCurrentIndex(0); - if (useDownloadPath) - { - const Path categoryDownloadPath = btSession->categoryDownloadPath(m_addTorrentParams.category); - const Path defaultDownloadPath = (useCategoryPaths && !categoryDownloadPath.isEmpty()) - ? categoryDownloadPath : btSession->downloadPath(); - m_ui->downloadPathEdit->setPlaceholder(defaultDownloadPath); - } - else - { - m_ui->downloadPathEdit->setPlaceholder(Path()); - } + m_ui->useDownloadPathComboBox->setCurrentIndex( + m_ui->useDownloadPathComboBox->findData(btSession->isDownloadPathEnabled())); } } else @@ -374,6 +368,7 @@ void AddTorrentParamsWidget::populateSavePathOptions() if (useAutoTMM) { m_ui->groupBoxSavePath->setEnabled(false); + m_ui->defaultsNoteLabel->setVisible(true); m_ui->savePathEdit->blockSignals(true); m_ui->savePathEdit->setSelectedPath(Path()); m_ui->downloadPathEdit->blockSignals(true); @@ -387,8 +382,11 @@ void AddTorrentParamsWidget::populateSavePathOptions() loadCustomSavePathOptions(); m_ui->groupBoxSavePath->setEnabled(true); + m_ui->defaultsNoteLabel->setVisible(false); m_ui->savePathEdit->blockSignals(false); m_ui->useDownloadPathComboBox->blockSignals(false); } } + + populateDefaultPaths(); } diff --git a/src/gui/addtorrentparamswidget.h b/src/gui/addtorrentparamswidget.h index 7cb27eeeb..3f61e55ae 100644 --- a/src/gui/addtorrentparamswidget.h +++ b/src/gui/addtorrentparamswidget.h @@ -52,9 +52,12 @@ public: private: void populate(); void loadCustomSavePathOptions(); + void loadCustomDownloadPath(); void loadCategorySavePathOptions(); + void populateDefaultPaths(); + void populateDefaultDownloadPath(); void populateSavePathOptions(); - void populateDownloadPathEdit(); + Ui::AddTorrentParamsWidget *m_ui; BitTorrent::AddTorrentParams m_addTorrentParams; diff --git a/src/gui/addtorrentparamswidget.ui b/src/gui/addtorrentparamswidget.ui index eaf34250d..e43d88169 100644 --- a/src/gui/addtorrentparamswidget.ui +++ b/src/gui/addtorrentparamswidget.ui @@ -51,6 +51,18 @@ Save at + + + + + true + + + + Note: the current defaults are displayed for reference. + + + @@ -113,7 +125,7 @@ - + Qt::Horizontal