diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 7d024d5db..5400f3843 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -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; diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 72f6e6a2a..7827b50e1 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -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 diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index b40622a7f..a0daae281 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -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 m_savePath; CachedSettingValue m_downloadPath; CachedSettingValue m_isDownloadPathEnabled; - CachedSettingValue m_isSubcategoriesEnabled; CachedSettingValue m_useCategoryPathsInManualMode; CachedSettingValue m_isAutoTMMDisabledByDefault; CachedSettingValue m_isDisableAutoTMMWhenCategoryChanged; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 84450fe4f..b46107325 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -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 diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index f1c3cca62..4f9d437bf 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -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())); diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 21435d809..48dd071f8 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -1381,13 +1381,6 @@ Manual: Various torrent properties (e.g. save path) must be assigned manually - - - - Use Subcategories - - - diff --git a/src/gui/transferlistfilters/categoryfiltermodel.cpp b/src/gui/transferlistfilters/categoryfiltermodel.cpp index dfab6672e..ccbfa36e0 100644 --- a/src/gui/transferlistfilters/categoryfiltermodel.cpp +++ b/src/gui/transferlistfilters/categoryfiltermodel.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2016-2023 Vladimir Golovnev + * Copyright (C) 2016-2025 Vladimir Golovnev * * 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))) { diff --git a/src/gui/transferlistfilters/categoryfiltermodel.h b/src/gui/transferlistfilters/categoryfiltermodel.h index fce28243d..3f5572d8b 100644 --- a/src/gui/transferlistfilters/categoryfiltermodel.h +++ b/src/gui/transferlistfilters/categoryfiltermodel.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2016-2023 Vladimir Golovnev + * Copyright (C) 2016-2025 Vladimir Golovnev * * 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; }; diff --git a/src/gui/transferlistfilters/categoryfilterwidget.cpp b/src/gui/transferlistfilters/categoryfilterwidget.cpp index 49bab70c4..215e124f7 100644 --- a/src/gui/transferlistfilters/categoryfilterwidget.cpp +++ b/src/gui/transferlistfilters/categoryfilterwidget.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2016 Vladimir Golovnev + * Copyright (C) 2016-2025 Vladimir Golovnev * * 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(); } diff --git a/src/gui/transferlistfilters/categoryfilterwidget.h b/src/gui/transferlistfilters/categoryfilterwidget.h index d340d9337..93ef02182 100644 --- a/src/gui/transferlistfilters/categoryfilterwidget.h +++ b/src/gui/transferlistfilters/categoryfilterwidget.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2016 Vladimir Golovnev + * Copyright (C) 2016-2025 Vladimir Golovnev * * 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; }; diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index 11d6bee7e..a9f3dae6c 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -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)) diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index 244b21b2f..4edf5f5c8 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -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; diff --git a/src/webui/webapplication.h b/src/webui/webapplication.h index ebac6207b..a752a3225 100644 --- a/src/webui/webapplication.h +++ b/src/webui/webapplication.h @@ -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; diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index 3aecd3409..1afa3a852 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -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); }; diff --git a/src/webui/www/private/scripts/contextmenu.js b/src/webui/www/private/scripts/contextmenu.js index ce6c3756e..fcf44c936 100644 --- a/src/webui/www/private/scripts/contextmenu.js +++ b/src/webui/www/private/scripts/contextmenu.js @@ -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"); diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 3465d7f03..d32c1ac9d 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -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) { diff --git a/src/webui/www/private/views/preferences.html b/src/webui/www/private/views/preferences.html index 76257e9bb..f5cbfe3a8 100644 --- a/src/webui/www/private/views/preferences.html +++ b/src/webui/www/private/views/preferences.html @@ -229,10 +229,6 @@ -
- - -
@@ -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;