diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 7fa4015e9ba..4750a6a8420 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1213,12 +1213,8 @@ void TorrentHandle::setName(const QString &name) bool TorrentHandle::setCategory(const QString &category) { if (m_category != category) { - if (!category.isEmpty()) { - if (!Session::isValidCategoryName(category)) return false; - if (!m_session->categories().contains(category)) - if (!m_session->addCategory(category)) - return false; - } + if (!category.isEmpty() && !m_session->categories().contains(category)) + return false; QString oldCategory = m_category; m_category = category; diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index d8fe4d46489..597a207e3c8 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -320,7 +320,7 @@ namespace // - "full_update": full data update flag // - "torrents": dictionary contains information about torrents. // - "torrents_removed": a list of hashes of removed torrents -// - "categories": list of categories +// - "categories": map of categories info // - "categories_removed": list of removed categories // - "server_state": map contains information about the state of the server // The keys of the 'torrents' dictionary are hashes of torrents. @@ -399,9 +399,15 @@ void SyncController::maindataAction() data["torrents"] = torrents; - QVariantList categories; - for (auto i = session->categories().cbegin(); i != session->categories().cend(); ++i) - categories << i.key(); + QVariantHash categories; + const auto categoriesList = session->categories(); + for (auto it = categoriesList.cbegin(); it != categoriesList.cend(); ++it) { + const auto key = it.key(); + categories[key] = QVariantMap { + {"name", key}, + {"savePath", it.value()} + }; + } data["categories"] = categories; diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index cdb5fd0045a..0b23e1e948c 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -738,7 +738,7 @@ void TorrentsController::setLocationAction() const QString newLocation {params()["location"].trimmed()}; if (newLocation.isEmpty()) - throw APIError(APIErrorType::BadParams, tr("Save path is empty")); + throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty")); // try to create the location if it does not exist if (!QDir(newLocation).mkpath(".")) @@ -809,6 +809,7 @@ void TorrentsController::setCategoryAction() const QStringList hashes {params()["hashes"].split('|')}; const QString category {params()["category"].trimmed()}; + applyToTorrents(hashes, [category](BitTorrent::TorrentHandle *torrent) { if (!torrent->setCategory(category)) @@ -821,10 +822,30 @@ void TorrentsController::createCategoryAction() checkParams({"category"}); const QString category {params()["category"].trimmed()}; - if (!BitTorrent::Session::isValidCategoryName(category) && !category.isEmpty()) + const QString savePath {params()["savePath"]}; + + if (category.isEmpty()) + throw APIError(APIErrorType::BadParams, tr("Category cannot be empty")); + + if (!BitTorrent::Session::isValidCategoryName(category)) throw APIError(APIErrorType::Conflict, tr("Incorrect category name")); - BitTorrent::Session::instance()->addCategory(category); + if (!BitTorrent::Session::instance()->addCategory(category, savePath)) + throw APIError(APIErrorType::Conflict, tr("Unable to create category")); +} + +void TorrentsController::editCategoryAction() +{ + checkParams({"category", "savePath"}); + + const QString category {params()["category"].trimmed()}; + const QString savePath {params()["savePath"]}; + + if (category.isEmpty()) + throw APIError(APIErrorType::BadParams, tr("Category cannot be empty")); + + if (!BitTorrent::Session::instance()->editCategory(category, savePath)) + throw APIError(APIErrorType::Conflict, tr("Unable to edit category")); } void TorrentsController::removeCategoriesAction() diff --git a/src/webui/api/torrentscontroller.h b/src/webui/api/torrentscontroller.h index 0abaa30a3af..5ddcaf6b0b1 100644 --- a/src/webui/api/torrentscontroller.h +++ b/src/webui/api/torrentscontroller.h @@ -53,6 +53,7 @@ private slots: void renameAction(); void setCategoryAction(); void createCategoryAction(); + void editCategoryAction(); void removeCategoriesAction(); void addAction(); void deleteAction(); diff --git a/src/webui/extra_translations.h b/src/webui/extra_translations.h index d06ad9a0e38..2d8ce11234d 100644 --- a/src/webui/extra_translations.h +++ b/src/webui/extra_translations.h @@ -78,7 +78,8 @@ const char *QBT_WEBUI_TRANSLATIONS[] = { QT_TRANSLATE_NOOP("HttpServer", "Set location"), QT_TRANSLATE_NOOP("HttpServer", "Limit upload rate"), QT_TRANSLATE_NOOP("HttpServer", "Limit download rate"), - QT_TRANSLATE_NOOP("HttpServer", "Rename torrent") + QT_TRANSLATE_NOOP("HttpServer", "Rename torrent"), + QT_TRANSLATE_NOOP("HttpServer", "Unable to create category") }; const struct { const char *source; const char *comment; } QBT_WEBUI_COMMENTED_TRANSLATIONS[] = { diff --git a/src/webui/www/private/filters.html b/src/webui/www/private/filters.html index 890431a4b1b..afe65ecb6e4 100644 --- a/src/webui/www/private/filters.html +++ b/src/webui/www/private/filters.html @@ -23,6 +23,9 @@ CreateCategory: function(element, ref) { createCategoryFN(); }, + EditCategory: function(element, ref) { + editCategoryFN(element.id); + }, DeleteCategory: function(element, ref) { removeCategoryFN(element.id); }, diff --git a/src/webui/www/private/index.html b/src/webui/www/private/index.html index 8947633ab2b..de6ccbb1591 100644 --- a/src/webui/www/private/index.html +++ b/src/webui/www/private/index.html @@ -143,6 +143,7 @@