mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-16 21:51:33 -06:00
committed by
GitHub
parent
260563d340
commit
93470f2080
@@ -165,8 +165,6 @@ namespace BitTorrent
|
||||
virtual bool addCategory(const QString &name, const CategoryOptions &options = {}) = 0;
|
||||
virtual bool editCategory(const QString &name, const CategoryOptions &options) = 0;
|
||||
virtual bool removeCategory(const QString &name) = 0;
|
||||
virtual bool isSubcategoriesEnabled() const = 0;
|
||||
virtual void setSubcategoriesEnabled(bool value) = 0;
|
||||
virtual bool useCategoryPathsInManualMode() const = 0;
|
||||
virtual void setUseCategoryPathsInManualMode(bool value) = 0;
|
||||
|
||||
|
||||
@@ -555,7 +555,6 @@ SessionImpl::SessionImpl(QObject *parent)
|
||||
, m_savePath(BITTORRENT_SESSION_KEY(u"DefaultSavePath"_s), specialFolderLocation(SpecialFolder::Downloads))
|
||||
, m_downloadPath(BITTORRENT_SESSION_KEY(u"TempPath"_s), (savePath() / Path(u"temp"_s)))
|
||||
, m_isDownloadPathEnabled(BITTORRENT_SESSION_KEY(u"TempPathEnabled"_s), false)
|
||||
, m_isSubcategoriesEnabled(BITTORRENT_SESSION_KEY(u"SubcategoriesEnabled"_s), false)
|
||||
, m_useCategoryPathsInManualMode(BITTORRENT_SESSION_KEY(u"UseCategoryPathsInManualMode"_s), false)
|
||||
, m_isAutoTMMDisabledByDefault(BITTORRENT_SESSION_KEY(u"DisableAutoTMMByDefault"_s), true)
|
||||
, m_isDisableAutoTMMWhenCategoryChanged(BITTORRENT_SESSION_KEY(u"DisableAutoTMMTriggers/CategoryChanged"_s), false)
|
||||
@@ -626,11 +625,6 @@ SessionImpl::SessionImpl(QObject *parent)
|
||||
enableBandwidthScheduler();
|
||||
|
||||
loadCategories();
|
||||
if (isSubcategoriesEnabled())
|
||||
{
|
||||
// if subcategories support changed manually
|
||||
m_categories = expandCategories(m_categories);
|
||||
}
|
||||
|
||||
const QStringList storedTags = m_storedTags.get();
|
||||
for (const QString &tagStr : storedTags)
|
||||
@@ -938,15 +932,8 @@ Path SessionImpl::categorySavePath(const QString &categoryName, const CategoryOp
|
||||
if (path.isEmpty())
|
||||
{
|
||||
// use implicit save path
|
||||
if (isSubcategoriesEnabled())
|
||||
{
|
||||
path = Utils::Fs::toValidPath(subcategoryName(categoryName));
|
||||
basePath = categorySavePath(parentCategoryName(categoryName));
|
||||
}
|
||||
else
|
||||
{
|
||||
path = Utils::Fs::toValidPath(categoryName);
|
||||
}
|
||||
path = Utils::Fs::toValidPath(subcategoryName(categoryName));
|
||||
basePath = categorySavePath(parentCategoryName(categoryName));
|
||||
}
|
||||
|
||||
return (path.isAbsolute() ? path : (basePath / path));
|
||||
@@ -966,8 +953,7 @@ Path SessionImpl::categoryDownloadPath(const QString &categoryName, const Catego
|
||||
if (categoryName.isEmpty())
|
||||
return downloadPath();
|
||||
|
||||
const bool useSubcategories = isSubcategoriesEnabled();
|
||||
const QString name = useSubcategories ? subcategoryName(categoryName) : categoryName;
|
||||
const QString name = subcategoryName(categoryName);
|
||||
const Path path = !downloadPathOption.path.isEmpty()
|
||||
? downloadPathOption.path
|
||||
: Utils::Fs::toValidPath(name); // use implicit download path
|
||||
@@ -975,7 +961,7 @@ Path SessionImpl::categoryDownloadPath(const QString &categoryName, const Catego
|
||||
if (path.isAbsolute())
|
||||
return path;
|
||||
|
||||
const QString parentName = useSubcategories ? parentCategoryName(categoryName) : QString();
|
||||
const QString parentName = parentCategoryName(categoryName);
|
||||
CategoryOptions parentOptions = categoryOptions(parentName);
|
||||
// Even if download path of parent category is disabled (directly or by inheritance)
|
||||
// we need to construct the one as if it would be enabled.
|
||||
@@ -994,7 +980,7 @@ DownloadPathOption SessionImpl::resolveCategoryDownloadPathOption(const QString
|
||||
if (option.has_value())
|
||||
return *option;
|
||||
|
||||
const QString parentName = isSubcategoriesEnabled() ? parentCategoryName(categoryName) : QString();
|
||||
const QString parentName = parentCategoryName(categoryName);
|
||||
return resolveCategoryDownloadPathOption(parentName, categoryOptions(parentName).downloadPath);
|
||||
}
|
||||
|
||||
@@ -1006,15 +992,12 @@ bool SessionImpl::addCategory(const QString &name, const CategoryOptions &option
|
||||
if (!isValidCategoryName(name) || m_categories.contains(name))
|
||||
return false;
|
||||
|
||||
if (isSubcategoriesEnabled())
|
||||
for (const QString &parent : asConst(expandCategory(name)))
|
||||
{
|
||||
for (const QString &parent : asConst(expandCategory(name)))
|
||||
if ((parent != name) && !m_categories.contains(parent))
|
||||
{
|
||||
if ((parent != name) && !m_categories.contains(parent))
|
||||
{
|
||||
m_categories[parent] = {};
|
||||
emit categoryAdded(parent);
|
||||
}
|
||||
m_categories[parent] = {};
|
||||
emit categoryAdded(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1070,21 +1053,18 @@ bool SessionImpl::removeCategory(const QString &name)
|
||||
|
||||
// remove stored category and its subcategories if exist
|
||||
bool result = false;
|
||||
if (isSubcategoriesEnabled())
|
||||
// remove subcategories
|
||||
const QString test = name + u'/';
|
||||
Algorithm::removeIf(m_categories, [this, &test, &result](const QString &category, const CategoryOptions &)
|
||||
{
|
||||
// remove subcategories
|
||||
const QString test = name + u'/';
|
||||
Algorithm::removeIf(m_categories, [this, &test, &result](const QString &category, const CategoryOptions &)
|
||||
if (category.startsWith(test))
|
||||
{
|
||||
if (category.startsWith(test))
|
||||
{
|
||||
result = true;
|
||||
emit categoryRemoved(category);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
result = true;
|
||||
emit categoryRemoved(category);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
result = (m_categories.remove(name) > 0) || result;
|
||||
|
||||
@@ -1098,32 +1078,6 @@ bool SessionImpl::removeCategory(const QString &name)
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SessionImpl::isSubcategoriesEnabled() const
|
||||
{
|
||||
return m_isSubcategoriesEnabled;
|
||||
}
|
||||
|
||||
void SessionImpl::setSubcategoriesEnabled(const bool value)
|
||||
{
|
||||
if (isSubcategoriesEnabled() == value) return;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// expand categories to include all parent categories
|
||||
m_categories = expandCategories(m_categories);
|
||||
// update stored categories
|
||||
storeCategories();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reload categories
|
||||
loadCategories();
|
||||
}
|
||||
|
||||
m_isSubcategoriesEnabled = value;
|
||||
emit subcategoriesSupportChanged();
|
||||
}
|
||||
|
||||
bool SessionImpl::useCategoryPathsInManualMode() const
|
||||
{
|
||||
return m_useCategoryPathsInManualMode;
|
||||
@@ -5584,6 +5538,8 @@ void SessionImpl::loadCategories()
|
||||
const auto categoryOptions = CategoryOptions::fromJSON(it.value().toObject());
|
||||
m_categories[categoryName] = categoryOptions;
|
||||
}
|
||||
|
||||
m_categories = expandCategories(m_categories);
|
||||
}
|
||||
|
||||
bool SessionImpl::hasPerTorrentRatioLimit() const
|
||||
|
||||
@@ -156,8 +156,6 @@ namespace BitTorrent
|
||||
bool addCategory(const QString &name, const CategoryOptions &options = {}) override;
|
||||
bool editCategory(const QString &name, const CategoryOptions &options) override;
|
||||
bool removeCategory(const QString &name) override;
|
||||
bool isSubcategoriesEnabled() const override;
|
||||
void setSubcategoriesEnabled(bool value) override;
|
||||
bool useCategoryPathsInManualMode() const override;
|
||||
void setUseCategoryPathsInManualMode(bool value) override;
|
||||
|
||||
@@ -754,7 +752,6 @@ namespace BitTorrent
|
||||
CachedSettingValue<Path> m_savePath;
|
||||
CachedSettingValue<Path> m_downloadPath;
|
||||
CachedSettingValue<bool> m_isDownloadPathEnabled;
|
||||
CachedSettingValue<bool> m_isSubcategoriesEnabled;
|
||||
CachedSettingValue<bool> m_useCategoryPathsInManualMode;
|
||||
CachedSettingValue<bool> m_isAutoTMMDisabledByDefault;
|
||||
CachedSettingValue<bool> m_isDisableAutoTMMWhenCategoryChanged;
|
||||
|
||||
@@ -934,7 +934,7 @@ bool TorrentImpl::belongsToCategory(const QString &category) const
|
||||
if (m_category == category)
|
||||
return true;
|
||||
|
||||
return (m_session->isSubcategoriesEnabled() && m_category.startsWith(category + u'/'));
|
||||
return m_category.startsWith(category + u'/');
|
||||
}
|
||||
|
||||
TagSet TorrentImpl::tags() const
|
||||
|
||||
@@ -625,7 +625,6 @@ void OptionsDialog::loadDownloadsTabOptions()
|
||||
m_ui->comboCategoryChanged->setCurrentIndex(session->isDisableAutoTMMWhenCategorySavePathChanged());
|
||||
m_ui->comboCategoryDefaultPathChanged->setCurrentIndex(session->isDisableAutoTMMWhenDefaultSavePathChanged());
|
||||
|
||||
m_ui->checkUseSubcategories->setChecked(session->isSubcategoriesEnabled());
|
||||
m_ui->checkUseCategoryPaths->setChecked(session->useCategoryPathsInManualMode());
|
||||
|
||||
m_ui->textSavePath->setDialogCaption(tr("Choose a save directory"));
|
||||
@@ -730,7 +729,6 @@ void OptionsDialog::loadDownloadsTabOptions()
|
||||
connect(m_ui->comboCategoryChanged, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->comboCategoryDefaultPathChanged, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||
|
||||
connect(m_ui->checkUseSubcategories, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->checkUseCategoryPaths, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||
|
||||
connect(m_ui->textSavePath, &FileSystemPathEdit::selectedPathChanged, this, &ThisType::enableApplyButton);
|
||||
@@ -802,7 +800,6 @@ void OptionsDialog::saveDownloadsTabOptions() const
|
||||
session->setDisableAutoTMMWhenCategorySavePathChanged(m_ui->comboCategoryChanged->currentIndex() == 1);
|
||||
session->setDisableAutoTMMWhenDefaultSavePathChanged(m_ui->comboCategoryDefaultPathChanged->currentIndex() == 1);
|
||||
|
||||
session->setSubcategoriesEnabled(m_ui->checkUseSubcategories->isChecked());
|
||||
session->setUseCategoryPathsInManualMode(m_ui->checkUseCategoryPaths->isChecked());
|
||||
|
||||
session->setSavePath(Path(m_ui->textSavePath->selectedPath()));
|
||||
|
||||
@@ -1381,13 +1381,6 @@ Manual: Various torrent properties (e.g. save path) must be assigned manually</s
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkUseSubcategories">
|
||||
<property name="text">
|
||||
<string>Use Subcategories</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkUseCategoryPaths">
|
||||
<property name="toolTip">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2016-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2016-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -324,17 +324,17 @@ void CategoryFilterModel::categoryAdded(const QString &categoryName)
|
||||
{
|
||||
CategoryModelItem *parent = m_rootItem;
|
||||
|
||||
if (m_isSubcategoriesEnabled)
|
||||
{
|
||||
QStringList expanded = BitTorrent::Session::expandCategory(categoryName);
|
||||
if (expanded.count() > 1)
|
||||
parent = findItem(expanded[expanded.count() - 2]);
|
||||
}
|
||||
const QStringList expanded = BitTorrent::Session::expandCategory(categoryName);
|
||||
if (expanded.count() > 1)
|
||||
parent = findItem(expanded[expanded.count() - 2]);
|
||||
|
||||
Q_ASSERT(parent);
|
||||
if (!parent) [[unlikely]]
|
||||
return;
|
||||
|
||||
const int row = parent->childCount();
|
||||
beginInsertRows(index(parent), row, row);
|
||||
new CategoryModelItem(
|
||||
parent, m_isSubcategoriesEnabled ? shortName(categoryName) : categoryName);
|
||||
new CategoryModelItem(parent, shortName(categoryName));
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
@@ -426,7 +426,6 @@ void CategoryFilterModel::populate()
|
||||
|
||||
const auto *session = BitTorrent::Session::instance();
|
||||
const auto torrents = session->torrents();
|
||||
m_isSubcategoriesEnabled = session->isSubcategoriesEnabled();
|
||||
|
||||
// All torrents
|
||||
m_rootItem->addChild(CategoryModelItem::UID_ALL
|
||||
@@ -440,31 +439,19 @@ void CategoryFilterModel::populate()
|
||||
, new CategoryModelItem(nullptr, tr("Uncategorized"), torrentsCount));
|
||||
|
||||
using BitTorrent::Torrent;
|
||||
if (m_isSubcategoriesEnabled)
|
||||
for (const QString &categoryName : asConst(session->categories()))
|
||||
{
|
||||
for (const QString &categoryName : asConst(session->categories()))
|
||||
CategoryModelItem *parent = m_rootItem;
|
||||
for (const QString &subcat : asConst(BitTorrent::Session::expandCategory(categoryName)))
|
||||
{
|
||||
CategoryModelItem *parent = m_rootItem;
|
||||
for (const QString &subcat : asConst(BitTorrent::Session::expandCategory(categoryName)))
|
||||
const QString subcatName = shortName(subcat);
|
||||
if (!parent->hasChild(subcatName))
|
||||
{
|
||||
const QString subcatName = shortName(subcat);
|
||||
if (!parent->hasChild(subcatName))
|
||||
{
|
||||
const int torrentsCount = std::ranges::count_if(torrents
|
||||
, [&subcat](const Torrent *torrent) { return torrent->category() == subcat; });
|
||||
new CategoryModelItem(parent, subcatName, torrentsCount);
|
||||
}
|
||||
parent = parent->child(subcatName);
|
||||
const int torrentsCount = std::ranges::count_if(torrents
|
||||
, [&subcat](const Torrent *torrent) { return torrent->category() == subcat; });
|
||||
new CategoryModelItem(parent, subcatName, torrentsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const QString &categoryName : asConst(session->categories()))
|
||||
{
|
||||
const int torrentsCount = std::ranges::count_if(torrents
|
||||
, [&categoryName](const Torrent *torrent) { return torrent->belongsToCategory(categoryName); });
|
||||
new CategoryModelItem(m_rootItem, categoryName, torrentsCount);
|
||||
parent = parent->child(subcatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,9 +461,6 @@ CategoryModelItem *CategoryFilterModel::findItem(const QString &fullName) const
|
||||
if (fullName.isEmpty())
|
||||
return m_rootItem->childAt(1); // "Uncategorized" item
|
||||
|
||||
if (!m_isSubcategoriesEnabled)
|
||||
return m_rootItem->child(fullName);
|
||||
|
||||
CategoryModelItem *item = m_rootItem;
|
||||
for (const QString &subcat : asConst(BitTorrent::Session::expandCategory(fullName)))
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2016-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2016-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -72,6 +72,5 @@ private:
|
||||
QModelIndex index(CategoryModelItem *item) const;
|
||||
CategoryModelItem *findItem(const QString &fullName) const;
|
||||
|
||||
bool m_isSubcategoriesEnabled = false;
|
||||
CategoryModelItem *m_rootItem = nullptr;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2016 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2016-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -72,9 +72,6 @@ CategoryFilterWidget::CategoryFilterWidget(QWidget *parent)
|
||||
#ifdef Q_OS_MACOS
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
#endif
|
||||
m_defaultIndentation = indentation();
|
||||
if (!BitTorrent::Session::instance()->isSubcategoriesEnabled())
|
||||
setIndentation(0);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
sortByColumn(0, Qt::AscendingOrder);
|
||||
setCurrentIndex(model()->index(0, 0));
|
||||
@@ -113,12 +110,8 @@ void CategoryFilterWidget::showMenu()
|
||||
const auto selectedRows = selectionModel()->selectedRows();
|
||||
if (!selectedRows.empty() && !CategoryFilterModel::isSpecialItem(selectedRows.first()))
|
||||
{
|
||||
if (BitTorrent::Session::instance()->isSubcategoriesEnabled())
|
||||
{
|
||||
menu->addAction(UIThemeManager::instance()->getIcon(u"list-add"_s), tr("Add subcategory...")
|
||||
, this, &CategoryFilterWidget::addSubcategory);
|
||||
}
|
||||
|
||||
menu->addAction(UIThemeManager::instance()->getIcon(u"list-add"_s), tr("Add subcategory...")
|
||||
, this, &CategoryFilterWidget::addSubcategory);
|
||||
menu->addAction(UIThemeManager::instance()->getIcon(u"edit-rename"_s, u"document-edit"_s), tr("Edit category...")
|
||||
, this, &CategoryFilterWidget::editCategory);
|
||||
menu->addAction(UIThemeManager::instance()->getIcon(u"edit-clear"_s, u"list-remove"_s), tr("Remove category")
|
||||
@@ -140,11 +133,6 @@ void CategoryFilterWidget::showMenu()
|
||||
|
||||
void CategoryFilterWidget::callUpdateGeometry()
|
||||
{
|
||||
if (!BitTorrent::Session::instance()->isSubcategoriesEnabled())
|
||||
setIndentation(0);
|
||||
else
|
||||
setIndentation(m_defaultIndentation);
|
||||
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2016 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2016-2025 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -60,6 +60,4 @@ private:
|
||||
QSize sizeHint() const override;
|
||||
QSize minimumSizeHint() const override;
|
||||
void rowsInserted(const QModelIndex &parent, int start, int end) override;
|
||||
|
||||
int m_defaultIndentation;
|
||||
};
|
||||
|
||||
@@ -174,7 +174,6 @@ void AppController::preferencesAction()
|
||||
data[u"torrent_changed_tmm_enabled"_s] = !session->isDisableAutoTMMWhenCategoryChanged();
|
||||
data[u"save_path_changed_tmm_enabled"_s] = !session->isDisableAutoTMMWhenDefaultSavePathChanged();
|
||||
data[u"category_changed_tmm_enabled"_s] = !session->isDisableAutoTMMWhenCategorySavePathChanged();
|
||||
data[u"use_subcategories"] = session->isSubcategoriesEnabled();
|
||||
data[u"save_path"_s] = session->savePath().toString();
|
||||
data[u"temp_path_enabled"_s] = session->isDownloadPathEnabled();
|
||||
data[u"temp_path"_s] = session->downloadPath().toString();
|
||||
@@ -593,8 +592,6 @@ void AppController::setPreferencesAction()
|
||||
session->setDisableAutoTMMWhenDefaultSavePathChanged(!it.value().toBool());
|
||||
if (hasKey(u"category_changed_tmm_enabled"_s))
|
||||
session->setDisableAutoTMMWhenCategorySavePathChanged(!it.value().toBool());
|
||||
if (hasKey(u"use_subcategories"_s))
|
||||
session->setSubcategoriesEnabled(it.value().toBool());
|
||||
if (hasKey(u"save_path"_s))
|
||||
session->setSavePath(Path(it.value().toString()));
|
||||
if (hasKey(u"temp_path_enabled"_s))
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace
|
||||
const QString KEY_SYNC_MAINDATA_QUEUEING = u"queueing"_s;
|
||||
const QString KEY_SYNC_MAINDATA_REFRESH_INTERVAL = u"refresh_interval"_s;
|
||||
const QString KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS = u"use_alt_speed_limits"_s;
|
||||
const QString KEY_SYNC_MAINDATA_USE_SUBCATEGORIES = u"use_subcategories"_s;
|
||||
|
||||
// Sync torrent peers keys
|
||||
const QString KEY_SYNC_TORRENT_PEERS_SHOW_FLAGS = u"show_flags"_s;
|
||||
@@ -617,7 +616,6 @@ void SyncController::makeMaindataSnapshot()
|
||||
m_maindataSnapshot.serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled();
|
||||
m_maindataSnapshot.serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled();
|
||||
m_maindataSnapshot.serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval();
|
||||
m_maindataSnapshot.serverState[KEY_SYNC_MAINDATA_USE_SUBCATEGORIES] = session->isSubcategoriesEnabled();
|
||||
}
|
||||
|
||||
QJsonObject SyncController::generateMaindataSyncData(const int id, const bool fullUpdate)
|
||||
@@ -771,7 +769,6 @@ QJsonObject SyncController::generateMaindataSyncData(const int id, const bool fu
|
||||
serverState[KEY_SYNC_MAINDATA_QUEUEING] = session->isQueueingSystemEnabled();
|
||||
serverState[KEY_SYNC_MAINDATA_USE_ALT_SPEED_LIMITS] = session->isAltGlobalSpeedLimitEnabled();
|
||||
serverState[KEY_SYNC_MAINDATA_REFRESH_INTERVAL] = session->refreshInterval();
|
||||
serverState[KEY_SYNC_MAINDATA_USE_SUBCATEGORIES] = session->isSubcategoriesEnabled();
|
||||
if (const QVariantMap syncData = processMap(m_maindataSnapshot.serverState, serverState); !syncData.isEmpty())
|
||||
{
|
||||
m_maindataSyncBuf.serverState = syncData;
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
inline const Utils::Version<3, 2> API_VERSION {2, 14, 1};
|
||||
inline const Utils::Version<3, 2> API_VERSION {2, 15, 0};
|
||||
|
||||
class APIController;
|
||||
class AuthController;
|
||||
|
||||
@@ -222,7 +222,6 @@ let alternativeSpeedLimits = false;
|
||||
let queueing_enabled = true;
|
||||
let serverSyncMainDataInterval = 1500;
|
||||
let customSyncMainDataInterval = null;
|
||||
let useSubcategories = true;
|
||||
const useAutoHideZeroStatusFilters = localPreferences.get("hide_zero_status_filters", "false") === "true";
|
||||
const displayFullURLTrackerColumn = localPreferences.get("full_url_tracker_column", "false") === "true";
|
||||
|
||||
@@ -634,7 +633,7 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
categoryName: category,
|
||||
categoryCount: categoryData.torrents.size,
|
||||
nameSegments: category.split("/"),
|
||||
...(useSubcategories && {
|
||||
...({
|
||||
children: [],
|
||||
isRoot: true,
|
||||
forceExpand: localPreferences.get(`category_${category}_collapsed`) === null
|
||||
@@ -659,32 +658,25 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
categoriesFragment.appendChild(createLink(CATEGORIES_ALL, "QBT_TR(All)QBT_TR[CONTEXT=CategoryFilterModel]", torrentsTable.getRowSize()));
|
||||
categoriesFragment.appendChild(createLink(CATEGORIES_UNCATEGORIZED, "QBT_TR(Uncategorized)QBT_TR[CONTEXT=CategoryFilterModel]", uncategorized));
|
||||
|
||||
if (useSubcategories) {
|
||||
categoryList.classList.add("subcategories");
|
||||
for (let i = 0; i < sortedCategories.length; ++i) {
|
||||
const category = sortedCategories[i];
|
||||
for (let j = (i + 1);
|
||||
((j < sortedCategories.length) && sortedCategories[j].categoryName.startsWith(`${category.categoryName}/`)); ++j) {
|
||||
const subcategory = sortedCategories[j];
|
||||
category.categoryCount += subcategory.categoryCount;
|
||||
category.forceExpand ||= subcategory.forceExpand;
|
||||
categoryList.classList.add("subcategories");
|
||||
for (let i = 0; i < sortedCategories.length; ++i) {
|
||||
const category = sortedCategories[i];
|
||||
for (let j = (i + 1);
|
||||
((j < sortedCategories.length) && sortedCategories[j].categoryName.startsWith(`${category.categoryName}/`)); ++j) {
|
||||
const subcategory = sortedCategories[j];
|
||||
category.categoryCount += subcategory.categoryCount;
|
||||
category.forceExpand ||= subcategory.forceExpand;
|
||||
|
||||
const isDirectSubcategory = (subcategory.nameSegments.length - category.nameSegments.length) === 1;
|
||||
if (isDirectSubcategory) {
|
||||
subcategory.isRoot = false;
|
||||
category.children.push(subcategory);
|
||||
}
|
||||
const isDirectSubcategory = (subcategory.nameSegments.length - category.nameSegments.length) === 1;
|
||||
if (isDirectSubcategory) {
|
||||
subcategory.isRoot = false;
|
||||
category.children.push(subcategory);
|
||||
}
|
||||
}
|
||||
for (const category of sortedCategories) {
|
||||
if (category.isRoot)
|
||||
createCategoryTree(category);
|
||||
}
|
||||
}
|
||||
else {
|
||||
categoryList.classList.remove("subcategories");
|
||||
for (const { categoryName, categoryCount } of sortedCategories)
|
||||
categoriesFragment.appendChild(createLink(categoryName, categoryName, categoryCount));
|
||||
for (const category of sortedCategories) {
|
||||
if (category.isRoot)
|
||||
createCategoryTree(category);
|
||||
}
|
||||
|
||||
categoryList.appendChild(categoriesFragment);
|
||||
@@ -1178,11 +1170,6 @@ window.addEventListener("DOMContentLoaded", (event) => {
|
||||
updateAltSpeedIcon(alternativeSpeedLimits);
|
||||
}
|
||||
|
||||
if (useSubcategories !== serverState.use_subcategories) {
|
||||
useSubcategories = serverState.use_subcategories;
|
||||
updateCategoryList();
|
||||
}
|
||||
|
||||
serverSyncMainDataInterval = Math.max(serverState.refresh_interval, 500);
|
||||
};
|
||||
|
||||
|
||||
@@ -585,10 +585,7 @@ window.qBittorrent.ContextMenu ??= (() => {
|
||||
if ((id !== CATEGORIES_ALL) && (id !== CATEGORIES_UNCATEGORIZED)) {
|
||||
this.showItem("editCategory");
|
||||
this.showItem("deleteCategory");
|
||||
if (useSubcategories)
|
||||
this.showItem("createSubcategory");
|
||||
else
|
||||
this.hideItem("createSubcategory");
|
||||
this.showItem("createSubcategory");
|
||||
}
|
||||
else {
|
||||
this.hideItem("editCategory");
|
||||
|
||||
@@ -1621,21 +1621,16 @@ window.qBittorrent.DynamicTable ??= (() => {
|
||||
return false;
|
||||
break; // do nothing
|
||||
|
||||
default:
|
||||
if (!useSubcategories) {
|
||||
if (category !== row["full_data"].category)
|
||||
default: {
|
||||
const selectedCategory = window.qBittorrent.Client.categoryMap.get(category);
|
||||
if (selectedCategory !== undefined) {
|
||||
const selectedCategoryName = `${category}/`;
|
||||
const torrentCategoryName = `${row["full_data"].category}/`;
|
||||
if (!torrentCategoryName.startsWith(selectedCategoryName))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
const selectedCategory = window.qBittorrent.Client.categoryMap.get(category);
|
||||
if (selectedCategory !== undefined) {
|
||||
const selectedCategoryName = `${category}/`;
|
||||
const torrentCategoryName = `${row["full_data"].category}/`;
|
||||
if (!torrentCategoryName.startsWith(selectedCategoryName))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
|
||||
@@ -229,10 +229,6 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="formRow">
|
||||
<input type="checkbox" id="use_subcategories_checkbox">
|
||||
<label for="use_subcategories_checkbox">QBT_TR(Use Subcategories)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<input type="checkbox" id="categoryPathsManualModeCheckbox" title="QBT_TR(Resolve relative Save Path against appropriate Category path instead of Default one)QBT_TR[CONTEXT=OptionsDialog]">
|
||||
<label for="categoryPathsManualModeCheckbox">QBT_TR(Use Category paths in Manual Mode)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
@@ -2332,7 +2328,6 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
document.getElementById("torrent_changed_tmm_combobox").value = pref.torrent_changed_tmm_enabled;
|
||||
document.getElementById("save_path_changed_tmm_combobox").value = pref.save_path_changed_tmm_enabled;
|
||||
document.getElementById("category_changed_tmm_combobox").value = pref.category_changed_tmm_enabled;
|
||||
document.getElementById("use_subcategories_checkbox").checked = pref.use_subcategories;
|
||||
document.getElementById("categoryPathsManualModeCheckbox").checked = pref.use_category_paths_in_manual_mode;
|
||||
document.getElementById("savepath_text").value = pref.save_path;
|
||||
document.getElementById("temppath_checkbox").checked = pref.temp_path_enabled;
|
||||
@@ -2754,7 +2749,6 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
settings["torrent_changed_tmm_enabled"] = (document.getElementById("torrent_changed_tmm_combobox").value === "true");
|
||||
settings["save_path_changed_tmm_enabled"] = (document.getElementById("save_path_changed_tmm_combobox").value === "true");
|
||||
settings["category_changed_tmm_enabled"] = (document.getElementById("category_changed_tmm_combobox").value === "true");
|
||||
settings["use_subcategories"] = document.getElementById("use_subcategories_checkbox").checked;
|
||||
settings["use_category_paths_in_manual_mode"] = document.getElementById("categoryPathsManualModeCheckbox").checked;
|
||||
settings["save_path"] = document.getElementById("savepath_text").value;
|
||||
settings["temp_path_enabled"] = document.getElementById("temppath_checkbox").checked;
|
||||
|
||||
Reference in New Issue
Block a user