From 905f1416572913cf0bb0d143b7da381cd544fad8 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Tue, 11 Apr 2023 12:17:48 +0300 Subject: [PATCH] Revamp "Automated RSS downloader" dialog --- src/base/bittorrent/addtorrentparams.cpp | 20 + src/base/bittorrent/addtorrentparams.h | 2 + src/base/rss/rss_autodownloader.cpp | 9 +- src/base/rss/rss_autodownloadrule.cpp | 233 +++++---- src/base/rss/rss_autodownloadrule.h | 14 +- src/gui/addtorrentparamswidget.h | 2 +- src/gui/rss/automatedrssdownloader.cpp | 193 +++----- src/gui/rss/automatedrssdownloader.h | 21 +- src/gui/rss/automatedrssdownloader.ui | 588 +++++++++-------------- 9 files changed, 464 insertions(+), 618 deletions(-) diff --git a/src/base/bittorrent/addtorrentparams.cpp b/src/base/bittorrent/addtorrentparams.cpp index cdbed3435..8e0725a6c 100644 --- a/src/base/bittorrent/addtorrentparams.cpp +++ b/src/base/bittorrent/addtorrentparams.cpp @@ -28,6 +28,8 @@ #include "addtorrentparams.h" +#include + #include #include #include @@ -97,6 +99,24 @@ namespace } } +bool BitTorrent::operator==(const AddTorrentParams &lhs, const AddTorrentParams &rhs) +{ + return std::tie(lhs.name, lhs.category, lhs.tags, + lhs.savePath, lhs.useDownloadPath, lhs.downloadPath, + lhs.sequential, lhs.firstLastPiecePriority, lhs.addForced, + lhs.addToQueueTop, lhs.addPaused, lhs.stopCondition, + lhs.filePaths, lhs.filePriorities, lhs.skipChecking, + lhs.contentLayout, lhs.useAutoTMM, lhs.uploadLimit, + lhs.downloadLimit, lhs.seedingTimeLimit, lhs.ratioLimit) + == std::tie(rhs.name, rhs.category, rhs.tags, + rhs.savePath, rhs.useDownloadPath, rhs.downloadPath, + rhs.sequential, rhs.firstLastPiecePriority, rhs.addForced, + rhs.addToQueueTop, rhs.addPaused, rhs.stopCondition, + rhs.filePaths, rhs.filePriorities, rhs.skipChecking, + rhs.contentLayout, rhs.useAutoTMM, rhs.uploadLimit, + rhs.downloadLimit, rhs.seedingTimeLimit, rhs.ratioLimit); +} + BitTorrent::AddTorrentParams BitTorrent::parseAddTorrentParams(const QJsonObject &jsonObj) { AddTorrentParams params; diff --git a/src/base/bittorrent/addtorrentparams.h b/src/base/bittorrent/addtorrentparams.h index 64f8d3eb7..66efe527c 100644 --- a/src/base/bittorrent/addtorrentparams.h +++ b/src/base/bittorrent/addtorrentparams.h @@ -70,6 +70,8 @@ namespace BitTorrent qreal ratioLimit = Torrent::USE_GLOBAL_RATIO; }; + bool operator==(const AddTorrentParams &lhs, const AddTorrentParams &rhs); + AddTorrentParams parseAddTorrentParams(const QJsonObject &jsonObj); QJsonObject serializeAddTorrentParams(const AddTorrentParams ¶ms); } diff --git a/src/base/rss/rss_autodownloader.cpp b/src/base/rss/rss_autodownloader.cpp index 6aab0504a..582390daf 100644 --- a/src/base/rss/rss_autodownloader.cpp +++ b/src/base/rss/rss_autodownloader.cpp @@ -430,15 +430,8 @@ void AutoDownloader::processJob(const QSharedPointer &job) m_dirty = true; storeDeferred(); - BitTorrent::AddTorrentParams params; - params.savePath = rule.savePath(); - params.category = rule.assignedCategory(); - params.addPaused = rule.addPaused(); - params.contentLayout = rule.torrentContentLayout(); - if (!rule.savePath().isEmpty()) - params.useAutoTMM = false; const auto torrentURL = job->articleData.value(Article::KeyTorrentURL).toString(); - BitTorrent::Session::instance()->addTorrent(torrentURL, params); + BitTorrent::Session::instance()->addTorrent(torrentURL, rule.addTorrentParams()); if (BitTorrent::MagnetUri(torrentURL).isValid()) { diff --git a/src/base/rss/rss_autodownloadrule.cpp b/src/base/rss/rss_autodownloadrule.cpp index e6db0aede..476f0fcb3 100644 --- a/src/base/rss/rss_autodownloadrule.cpp +++ b/src/base/rss/rss_autodownloadrule.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2017 Vladimir Golovnev + * Copyright (C) 2017-2023 Vladimir Golovnev * Copyright (C) 2010 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -101,22 +101,24 @@ namespace } } -const QString Str_Name = u"name"_qs; -const QString Str_Enabled = u"enabled"_qs; -const QString Str_UseRegex = u"useRegex"_qs; -const QString Str_MustContain = u"mustContain"_qs; -const QString Str_MustNotContain = u"mustNotContain"_qs; -const QString Str_EpisodeFilter = u"episodeFilter"_qs; -const QString Str_AffectedFeeds = u"affectedFeeds"_qs; -const QString Str_SavePath = u"savePath"_qs; -const QString Str_AssignedCategory = u"assignedCategory"_qs; -const QString Str_LastMatch = u"lastMatch"_qs; -const QString Str_IgnoreDays = u"ignoreDays"_qs; -const QString Str_AddPaused = u"addPaused"_qs; -const QString Str_CreateSubfolder = u"createSubfolder"_qs; -const QString Str_ContentLayout = u"torrentContentLayout"_qs; -const QString Str_SmartFilter = u"smartFilter"_qs; -const QString Str_PreviouslyMatched = u"previouslyMatchedEpisodes"_qs; +const QString S_NAME = u"name"_qs; +const QString S_ENABLED = u"enabled"_qs; +const QString S_USE_REGEX = u"useRegex"_qs; +const QString S_MUST_CONTAIN = u"mustContain"_qs; +const QString S_MUST_NOT_CONTAIN = u"mustNotContain"_qs; +const QString S_EPISODE_FILTER = u"episodeFilter"_qs; +const QString S_AFFECTED_FEEDS = u"affectedFeeds"_qs; +const QString S_LAST_MATCH = u"lastMatch"_qs; +const QString S_IGNORE_DAYS = u"ignoreDays"_qs; +const QString S_SMART_FILTER = u"smartFilter"_qs; +const QString S_PREVIOUSLY_MATCHED = u"previouslyMatchedEpisodes"_qs; + +const QString S_SAVE_PATH = u"savePath"_qs; +const QString S_ASSIGNED_CATEGORY = u"assignedCategory"_qs; +const QString S_ADD_PAUSED = u"addPaused"_qs; +const QString S_CONTENT_LAYOUT = u"torrentContentLayout"_qs; + +const QString S_TORRENT_PARAMS = u"torrentParams"_qs; namespace RSS { @@ -133,10 +135,7 @@ namespace RSS int ignoreDays = 0; QDateTime lastMatch; - Path savePath; - QString category; - std::optional addPaused; - std::optional contentLayout; + BitTorrent::AddTorrentParams addTorrentParams; bool smartFilter = false; QStringList previouslyMatchedEpisodes; @@ -155,11 +154,8 @@ namespace RSS && (left.useRegex == right.useRegex) && (left.ignoreDays == right.ignoreDays) && (left.lastMatch == right.lastMatch) - && (left.savePath == right.savePath) - && (left.category == right.category) - && (left.addPaused == right.addPaused) - && (left.contentLayout == right.contentLayout) - && (left.smartFilter == right.smartFilter); + && (left.smartFilter == right.smartFilter) + && (left.addTorrentParams == right.addTorrentParams); } }; @@ -458,64 +454,45 @@ AutoDownloadRule &AutoDownloadRule::operator=(const AutoDownloadRule &other) QJsonObject AutoDownloadRule::toJsonObject() const { - return {{Str_Enabled, isEnabled()} - , {Str_UseRegex, useRegex()} - , {Str_MustContain, mustContain()} - , {Str_MustNotContain, mustNotContain()} - , {Str_EpisodeFilter, episodeFilter()} - , {Str_AffectedFeeds, QJsonArray::fromStringList(feedURLs())} - , {Str_SavePath, savePath().toString()} - , {Str_AssignedCategory, assignedCategory()} - , {Str_LastMatch, lastMatch().toString(Qt::RFC2822Date)} - , {Str_IgnoreDays, ignoreDays()} - , {Str_AddPaused, toJsonValue(addPaused())} - , {Str_ContentLayout, contentLayoutToJsonValue(torrentContentLayout())} - , {Str_SmartFilter, useSmartFilter()} - , {Str_PreviouslyMatched, QJsonArray::fromStringList(previouslyMatchedEpisodes())}}; + const BitTorrent::AddTorrentParams &addTorrentParams = m_dataPtr->addTorrentParams; + + return {{S_ENABLED, isEnabled()} + , {S_USE_REGEX, useRegex()} + , {S_MUST_CONTAIN, mustContain()} + , {S_MUST_NOT_CONTAIN, mustNotContain()} + , {S_EPISODE_FILTER, episodeFilter()} + , {S_AFFECTED_FEEDS, QJsonArray::fromStringList(feedURLs())} + , {S_LAST_MATCH, lastMatch().toString(Qt::RFC2822Date)} + , {S_IGNORE_DAYS, ignoreDays()} + , {S_SMART_FILTER, useSmartFilter()} + , {S_PREVIOUSLY_MATCHED, QJsonArray::fromStringList(previouslyMatchedEpisodes())} + + // TODO: The following code is deprecated. Replace with the commented one after several releases in 4.6.x. + // === BEGIN DEPRECATED CODE === // + , {S_ADD_PAUSED, toJsonValue(addTorrentParams.addPaused)} + , {S_CONTENT_LAYOUT, contentLayoutToJsonValue(addTorrentParams.contentLayout)} + , {S_SAVE_PATH, addTorrentParams.savePath.toString()} + , {S_ASSIGNED_CATEGORY, addTorrentParams.category} + // === END DEPRECATED CODE === // + + , {S_TORRENT_PARAMS, BitTorrent::serializeAddTorrentParams(addTorrentParams)} + }; } AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, const QString &name) { - AutoDownloadRule rule(name.isEmpty() ? jsonObj.value(Str_Name).toString() : name); + AutoDownloadRule rule {(name.isEmpty() ? jsonObj.value(S_NAME).toString() : name)}; - rule.setUseRegex(jsonObj.value(Str_UseRegex).toBool(false)); - rule.setMustContain(jsonObj.value(Str_MustContain).toString()); - rule.setMustNotContain(jsonObj.value(Str_MustNotContain).toString()); - rule.setEpisodeFilter(jsonObj.value(Str_EpisodeFilter).toString()); - rule.setEnabled(jsonObj.value(Str_Enabled).toBool(true)); - rule.setSavePath(Path(jsonObj.value(Str_SavePath).toString())); - rule.setCategory(jsonObj.value(Str_AssignedCategory).toString()); - rule.setAddPaused(toOptionalBool(jsonObj.value(Str_AddPaused))); + rule.setUseRegex(jsonObj.value(S_USE_REGEX).toBool(false)); + rule.setMustContain(jsonObj.value(S_MUST_CONTAIN).toString()); + rule.setMustNotContain(jsonObj.value(S_MUST_NOT_CONTAIN).toString()); + rule.setEpisodeFilter(jsonObj.value(S_EPISODE_FILTER).toString()); + rule.setEnabled(jsonObj.value(S_ENABLED).toBool(true)); + rule.setLastMatch(QDateTime::fromString(jsonObj.value(S_LAST_MATCH).toString(), Qt::RFC2822Date)); + rule.setIgnoreDays(jsonObj.value(S_IGNORE_DAYS).toInt()); + rule.setUseSmartFilter(jsonObj.value(S_SMART_FILTER).toBool(false)); - // TODO: The following code is deprecated. Replace with the commented one after several releases in 4.4.x. - // === BEGIN DEPRECATED CODE === // - if (jsonObj.contains(Str_ContentLayout)) - { - rule.setTorrentContentLayout(jsonValueToContentLayout(jsonObj.value(Str_ContentLayout))); - } - else - { - const std::optional createSubfolder = toOptionalBool(jsonObj.value(Str_CreateSubfolder)); - std::optional contentLayout; - if (createSubfolder.has_value()) - { - contentLayout = (*createSubfolder - ? BitTorrent::TorrentContentLayout::Original - : BitTorrent::TorrentContentLayout::NoSubfolder); - } - - rule.setTorrentContentLayout(contentLayout); - } - // === END DEPRECATED CODE === // - // === BEGIN REPLACEMENT CODE === // -// rule.setTorrentContentLayout(jsonValueToContentLayout(jsonObj.value(Str_ContentLayout))); - // === END REPLACEMENT CODE === // - - rule.setLastMatch(QDateTime::fromString(jsonObj.value(Str_LastMatch).toString(), Qt::RFC2822Date)); - rule.setIgnoreDays(jsonObj.value(Str_IgnoreDays).toInt()); - rule.setUseSmartFilter(jsonObj.value(Str_SmartFilter).toBool(false)); - - const QJsonValue feedsVal = jsonObj.value(Str_AffectedFeeds); + const QJsonValue feedsVal = jsonObj.value(S_AFFECTED_FEEDS); QStringList feedURLs; if (feedsVal.isString()) feedURLs << feedsVal.toString(); @@ -523,7 +500,7 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co feedURLs << urlVal.toString(); rule.setFeedURLs(feedURLs); - const QJsonValue previouslyMatchedVal = jsonObj.value(Str_PreviouslyMatched); + const QJsonValue previouslyMatchedVal = jsonObj.value(S_PREVIOUSLY_MATCHED); QStringList previouslyMatched; if (previouslyMatchedVal.isString()) { @@ -536,20 +513,61 @@ AutoDownloadRule AutoDownloadRule::fromJsonObject(const QJsonObject &jsonObj, co } rule.setPreviouslyMatchedEpisodes(previouslyMatched); + // TODO: The following code is deprecated. Replace with the commented one after several releases in 4.6.x. + // === BEGIN DEPRECATED CODE === // + BitTorrent::AddTorrentParams addTorrentParams; + if (auto it = jsonObj.find(S_TORRENT_PARAMS); it != jsonObj.end()) + { + addTorrentParams = BitTorrent::parseAddTorrentParams(it->toObject()); + } + else + { + addTorrentParams.savePath = Path(jsonObj.value(S_SAVE_PATH).toString()); + addTorrentParams.category = jsonObj.value(S_ASSIGNED_CATEGORY).toString(); + addTorrentParams.addPaused = toOptionalBool(jsonObj.value(S_ADD_PAUSED)); + if (!addTorrentParams.savePath.isEmpty()) + addTorrentParams.useAutoTMM = false; + + if (jsonObj.contains(S_CONTENT_LAYOUT)) + { + addTorrentParams.contentLayout = jsonValueToContentLayout(jsonObj.value(S_CONTENT_LAYOUT)); + } + else + { + const std::optional createSubfolder = toOptionalBool(jsonObj.value(u"createSubfolder")); + std::optional contentLayout; + if (createSubfolder.has_value()) + { + contentLayout = (*createSubfolder + ? BitTorrent::TorrentContentLayout::Original + : BitTorrent::TorrentContentLayout::NoSubfolder); + } + + addTorrentParams.contentLayout = contentLayout; + } + } + rule.setAddTorrentParams(addTorrentParams); + // === END DEPRECATED CODE === // + // === BEGIN REPLACEMENT CODE === // + // rule.setAddTorrentParams(BitTorrent::parseAddTorrentParams(jsonObj.value(S_TORRENT_PARAMS).object())); + // === END REPLACEMENT CODE === // + return rule; } QVariantHash AutoDownloadRule::toLegacyDict() const { + const BitTorrent::AddTorrentParams &addTorrentParams = m_dataPtr->addTorrentParams; + return {{u"name"_qs, name()}, {u"must_contain"_qs, mustContain()}, {u"must_not_contain"_qs, mustNotContain()}, - {u"save_path"_qs, savePath().toString()}, + {u"save_path"_qs, addTorrentParams.savePath.toString()}, {u"affected_feeds"_qs, feedURLs()}, {u"enabled"_qs, isEnabled()}, - {u"category_assigned"_qs, assignedCategory()}, + {u"category_assigned"_qs, addTorrentParams.category}, {u"use_regex"_qs, useRegex()}, - {u"add_paused"_qs, toAddPausedLegacy(addPaused())}, + {u"add_paused"_qs, toAddPausedLegacy(addTorrentParams.addPaused)}, {u"episode_filter"_qs, episodeFilter()}, {u"last_match"_qs, lastMatch()}, {u"ignore_days"_qs, ignoreDays()}}; @@ -557,7 +575,14 @@ QVariantHash AutoDownloadRule::toLegacyDict() const AutoDownloadRule AutoDownloadRule::fromLegacyDict(const QVariantHash &dict) { - AutoDownloadRule rule(dict.value(u"name"_qs).toString()); + BitTorrent::AddTorrentParams addTorrentParams; + addTorrentParams.savePath = Path(dict.value(u"save_path"_qs).toString()); + addTorrentParams.category = dict.value(u"category_assigned"_qs).toString(); + addTorrentParams.addPaused = addPausedLegacyToOptionalBool(dict.value(u"add_paused"_qs).toInt()); + if (!addTorrentParams.savePath.isEmpty()) + addTorrentParams.useAutoTMM = false; + + AutoDownloadRule rule {dict.value(u"name"_qs).toString()}; rule.setUseRegex(dict.value(u"use_regex"_qs, false).toBool()); rule.setMustContain(dict.value(u"must_contain"_qs).toString()); @@ -565,11 +590,9 @@ AutoDownloadRule AutoDownloadRule::fromLegacyDict(const QVariantHash &dict) rule.setEpisodeFilter(dict.value(u"episode_filter"_qs).toString()); rule.setFeedURLs(dict.value(u"affected_feeds"_qs).toStringList()); rule.setEnabled(dict.value(u"enabled"_qs, false).toBool()); - rule.setSavePath(Path(dict.value(u"save_path"_qs).toString())); - rule.setCategory(dict.value(u"category_assigned"_qs).toString()); - rule.setAddPaused(addPausedLegacyToOptionalBool(dict.value(u"add_paused"_qs).toInt())); rule.setLastMatch(dict.value(u"last_match"_qs).toDateTime()); rule.setIgnoreDays(dict.value(u"ignore_days"_qs).toInt()); + rule.setAddTorrentParams(addTorrentParams); return rule; } @@ -622,44 +645,14 @@ void AutoDownloadRule::setName(const QString &name) m_dataPtr->name = name; } -Path AutoDownloadRule::savePath() const +BitTorrent::AddTorrentParams AutoDownloadRule::addTorrentParams() const { - return m_dataPtr->savePath; + return m_dataPtr->addTorrentParams; } -void AutoDownloadRule::setSavePath(const Path &savePath) +void AutoDownloadRule::setAddTorrentParams(BitTorrent::AddTorrentParams addTorrentParams) { - m_dataPtr->savePath = savePath; -} - -std::optional AutoDownloadRule::addPaused() const -{ - return m_dataPtr->addPaused; -} - -void AutoDownloadRule::setAddPaused(const std::optional addPaused) -{ - m_dataPtr->addPaused = addPaused; -} - -std::optional AutoDownloadRule::torrentContentLayout() const -{ - return m_dataPtr->contentLayout; -} - -void AutoDownloadRule::setTorrentContentLayout(const std::optional contentLayout) -{ - m_dataPtr->contentLayout = contentLayout; -} - -QString AutoDownloadRule::assignedCategory() const -{ - return m_dataPtr->category; -} - -void AutoDownloadRule::setCategory(const QString &category) -{ - m_dataPtr->category = category; + m_dataPtr->addTorrentParams = std::move(addTorrentParams); } bool AutoDownloadRule::isEnabled() const diff --git a/src/base/rss/rss_autodownloadrule.h b/src/base/rss/rss_autodownloadrule.h index a37d14f91..92050468b 100644 --- a/src/base/rss/rss_autodownloadrule.h +++ b/src/base/rss/rss_autodownloadrule.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2017 Vladimir Golovnev + * Copyright (C) 2017-2023 Vladimir Golovnev * Copyright (C) 2010 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -35,7 +35,7 @@ #include #include "base/global.h" -#include "base/bittorrent/torrentcontentlayout.h" +#include "base/bittorrent/addtorrentparams.h" #include "base/pathfwd.h" class QDateTime; @@ -81,14 +81,8 @@ namespace RSS QStringList previouslyMatchedEpisodes() const; void setPreviouslyMatchedEpisodes(const QStringList &previouslyMatchedEpisodes); - Path savePath() const; - void setSavePath(const Path &savePath); - std::optional addPaused() const; - void setAddPaused(std::optional addPaused); - std::optional torrentContentLayout() const; - void setTorrentContentLayout(std::optional contentLayout); - QString assignedCategory() const; - void setCategory(const QString &category); + BitTorrent::AddTorrentParams addTorrentParams() const; + void setAddTorrentParams(BitTorrent::AddTorrentParams addTorrentParams); bool matches(const QVariantHash &articleData) const; bool accepts(const QVariantHash &articleData); diff --git a/src/gui/addtorrentparamswidget.h b/src/gui/addtorrentparamswidget.h index a255659fa..7cb27eeeb 100644 --- a/src/gui/addtorrentparamswidget.h +++ b/src/gui/addtorrentparamswidget.h @@ -43,7 +43,7 @@ class AddTorrentParamsWidget final : public QWidget Q_DISABLE_COPY_MOVE(AddTorrentParamsWidget) public: - explicit AddTorrentParamsWidget(BitTorrent::AddTorrentParams addTorrentParams, QWidget *parent = nullptr); + explicit AddTorrentParamsWidget(BitTorrent::AddTorrentParams addTorrentParams = {}, QWidget *parent = nullptr); ~AddTorrentParamsWidget() override; void setAddTorrentParams(BitTorrent::AddTorrentParams addTorrentParams); diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index c5add9633..9f35afd6b 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2017 Vladimir Golovnev + * Copyright (C) 2017, 2023 Vladimir Golovnev * Copyright (C) 2010 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -50,6 +50,7 @@ #include "base/utils/compare.h" #include "base/utils/io.h" #include "base/utils/string.h" +#include "gui/addtorrentparamswidget.h" #include "gui/autoexpandabledialog.h" #include "gui/torrentcategorydialog.h" #include "gui/uithememanager.h" @@ -61,37 +62,44 @@ const QString EXT_LEGACY = u".rssrules"_qs; AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent) : QDialog(parent) - , m_formatFilterJSON(u"%1 (*%2)"_qs.arg(tr("Rules"), EXT_JSON)) - , m_formatFilterLegacy(u"%1 (*%2)"_qs.arg(tr("Rules (legacy)"), EXT_LEGACY)) - , m_ui(new Ui::AutomatedRssDownloader) + , m_formatFilterJSON {u"%1 (*%2)"_qs.arg(tr("Rules"), EXT_JSON)} + , m_formatFilterLegacy {u"%1 (*%2)"_qs.arg(tr("Rules (legacy)"), EXT_LEGACY)} + , m_ui {new Ui::AutomatedRssDownloader} + , m_addTorrentParamsWidget {new AddTorrentParamsWidget} , m_storeDialogSize {u"RssFeedDownloader/geometrySize"_qs} #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) - , m_storeHSplitterSize {u"GUI/Qt6/RSSFeedDownloader/HSplitterSizes"_qs} + , m_storeMainSplitterState {u"GUI/Qt6/RSSFeedDownloader/HSplitterSizes"_qs} + , m_storeRuleDefSplitterState {u"GUI/Qt6/RSSFeedDownloader/RuleDefSplitterState"_qs} #else - , m_storeHSplitterSize {u"RssFeedDownloader/qt5/hsplitterSizes"_qs} + , m_storeMainSplitterState {u"RssFeedDownloader/qt5/hsplitterSizes"_qs} + , m_storeRuleDefSplitterState {u"RssFeedDownloader/qt5/RuleDefSplitterState"_qs} #endif - { m_ui->setupUi(this); + m_ui->torrentParametersGroupBox->layout()->addWidget(m_addTorrentParamsWidget); + + connect(m_ui->addRuleBtn, &QPushButton::clicked, this, &AutomatedRssDownloader::onAddRuleBtnClicked); + connect(m_ui->removeRuleBtn, &QPushButton::clicked, this, &AutomatedRssDownloader::onRemoveRuleBtnClicked); + connect(m_ui->exportBtn, &QPushButton::clicked, this, &AutomatedRssDownloader::onExportBtnClicked); + connect(m_ui->importBtn, &QPushButton::clicked, this, &AutomatedRssDownloader::onImportBtnClicked); + connect(m_ui->renameRuleBtn, &QPushButton::clicked, this, &AutomatedRssDownloader::onRenameRuleBtnClicked); + // Icons m_ui->renameRuleBtn->setIcon(UIThemeManager::instance()->getIcon(u"edit-rename"_qs)); m_ui->removeRuleBtn->setIcon(UIThemeManager::instance()->getIcon(u"edit-clear"_qs, u"list-remove"_qs)); m_ui->addRuleBtn->setIcon(UIThemeManager::instance()->getIcon(u"list-add"_qs)); - m_ui->addCategoryBtn->setIcon(UIThemeManager::instance()->getIcon(u"list-add"_qs)); // Ui Settings - m_ui->listRules->setSortingEnabled(true); - m_ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection); - m_ui->treeMatchingArticles->setSortingEnabled(true); - m_ui->treeMatchingArticles->sortByColumn(0, Qt::AscendingOrder); - m_ui->hsplitter->setCollapsible(0, false); - m_ui->hsplitter->setCollapsible(1, false); - m_ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible - m_ui->lineSavePath->setDialogCaption(tr("Destination directory")); - m_ui->lineSavePath->setMode(FileSystemPathEdit::Mode::DirectorySave); + m_ui->ruleList->setSortingEnabled(true); + m_ui->ruleList->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_ui->matchingArticlesTree->setSortingEnabled(true); + m_ui->matchingArticlesTree->sortByColumn(0, Qt::AscendingOrder); + m_ui->mainSplitter->setCollapsible(0, false); + m_ui->mainSplitter->setCollapsible(1, false); + m_ui->mainSplitter->setCollapsible(2, true); // Only the preview list is collapsible connect(m_ui->checkRegex, &QAbstractButton::toggled, this, &AutomatedRssDownloader::updateFieldsToolTips); - connect(m_ui->listRules, &QWidget::customContextMenuRequested, this, &AutomatedRssDownloader::displayRulesListMenu); + connect(m_ui->ruleList, &QWidget::customContextMenuRequested, this, &AutomatedRssDownloader::displayRulesListMenu); m_episodeRegex = new QRegularExpression(u"^(^\\d{1,4}x(\\d{1,4}(-(\\d{1,4})?)?;){1,}){1,1}"_qs , QRegularExpression::CaseInsensitiveOption); @@ -106,7 +114,6 @@ AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent) + u"
  • " + tr("Infinite range: 1x25-; matches episodes 25 and upward of season one, and all episodes of later seasons") + u"
  • " + u""; m_ui->lineEFilter->setToolTip(tip); - initCategoryCombobox(); loadSettings(); connect(RSS::AutoDownloader::instance(), &RSS::AutoDownloader::ruleAdded, this, &AutomatedRssDownloader::handleRuleAdded); @@ -130,27 +137,28 @@ AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent) connect(m_ui->listFeeds, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleFeedCheckStateChange); - connect(m_ui->listRules, &QListWidget::itemSelectionChanged, this, &AutomatedRssDownloader::updateRuleDefinitionBox); - connect(m_ui->listRules, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleRuleCheckStateChange); + connect(m_ui->ruleList, &QListWidget::itemSelectionChanged, this, &AutomatedRssDownloader::updateRuleDefinitionBox); + connect(m_ui->ruleList, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleRuleCheckStateChange); - const auto *editHotkey = new QShortcut(Qt::Key_F2, m_ui->listRules, nullptr, nullptr, Qt::WidgetShortcut); + const auto *editHotkey = new QShortcut(Qt::Key_F2, m_ui->ruleList, nullptr, nullptr, Qt::WidgetShortcut); connect(editHotkey, &QShortcut::activated, this, &AutomatedRssDownloader::renameSelectedRule); - const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_ui->listRules, nullptr, nullptr, Qt::WidgetShortcut); - connect(deleteHotkey, &QShortcut::activated, this, &AutomatedRssDownloader::on_removeRuleBtn_clicked); + const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_ui->ruleList, nullptr, nullptr, Qt::WidgetShortcut); + connect(deleteHotkey, &QShortcut::activated, this, &AutomatedRssDownloader::onRemoveRuleBtnClicked); - connect(m_ui->listRules, &QAbstractItemView::doubleClicked, this, &AutomatedRssDownloader::renameSelectedRule); + connect(m_ui->ruleList, &QAbstractItemView::doubleClicked, this, &AutomatedRssDownloader::renameSelectedRule); loadFeedList(); - m_ui->listRules->blockSignals(true); + m_ui->ruleList->blockSignals(true); for (const RSS::AutoDownloadRule &rule : asConst(RSS::AutoDownloader::instance()->rules())) createRuleItem(rule); - m_ui->listRules->blockSignals(false); + m_ui->ruleList->blockSignals(false); updateRuleDefinitionBox(); if (RSS::AutoDownloader::instance()->isProcessingEnabled()) m_ui->labelWarn->hide(); + connect(RSS::AutoDownloader::instance(), &RSS::AutoDownloader::processingStateChanged , this, &AutomatedRssDownloader::handleProcessingStateChanged); } @@ -170,19 +178,23 @@ void AutomatedRssDownloader::loadSettings() if (const QSize dialogSize = m_storeDialogSize; dialogSize.isValid()) resize(dialogSize); - if (const QByteArray hSplitterSize = m_storeHSplitterSize; !hSplitterSize.isEmpty()) - m_ui->hsplitter->restoreState(hSplitterSize); + if (const QByteArray mainSplitterSize = m_storeMainSplitterState; !mainSplitterSize.isEmpty()) + m_ui->mainSplitter->restoreState(mainSplitterSize); + + if (const QByteArray ruleDefSplitterSize = m_storeRuleDefSplitterState; !ruleDefSplitterSize.isEmpty()) + m_ui->ruleDefSplitter->restoreState(ruleDefSplitterSize); } void AutomatedRssDownloader::saveSettings() { m_storeDialogSize = size(); - m_storeHSplitterSize = m_ui->hsplitter->saveState(); + m_storeMainSplitterState = m_ui->mainSplitter->saveState(); + m_storeRuleDefSplitterState = m_ui->ruleDefSplitter->saveState(); } void AutomatedRssDownloader::createRuleItem(const RSS::AutoDownloadRule &rule) { - QListWidgetItem *item = new QListWidgetItem(rule.name(), m_ui->listRules); + QListWidgetItem *item = new QListWidgetItem(rule.name(), m_ui->ruleList); m_itemsByRuleName.insert(rule.name(), item); item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(rule.isEnabled() ? Qt::Checked : Qt::Unchecked); @@ -211,7 +223,7 @@ void AutomatedRssDownloader::updateFeedList() if (m_currentRuleItem) selection << m_currentRuleItem; else - selection = m_ui->listRules->selectedItems(); + selection = m_ui->ruleList->selectedItems(); bool enable = !selection.isEmpty(); @@ -248,7 +260,7 @@ void AutomatedRssDownloader::updateFeedList() void AutomatedRssDownloader::updateRuleDefinitionBox() { - const QList selection = m_ui->listRules->selectedItems(); + const QList selection = m_ui->ruleList->selectedItems(); QListWidgetItem *currentRuleItem = ((selection.count() == 1) ? selection.first() : nullptr); // Enable the edit rule button but only if we have 1 rule selected @@ -261,7 +273,7 @@ void AutomatedRssDownloader::updateRuleDefinitionBox() { saveEditedRule(); // Save previous rule first m_currentRuleItem = currentRuleItem; - //m_ui->listRules->setCurrentItem(m_currentRuleItem); + //m_ui->ruleList->setCurrentItem(m_currentRuleItem); } // Update rule definition box @@ -269,31 +281,20 @@ void AutomatedRssDownloader::updateRuleDefinitionBox() { m_currentRule = RSS::AutoDownloader::instance()->ruleByName(m_currentRuleItem->text()); + m_addTorrentParamsWidget->setAddTorrentParams(m_currentRule.addTorrentParams()); + m_ui->lineContains->setText(m_currentRule.mustContain()); m_ui->lineNotContains->setText(m_currentRule.mustNotContain()); if (!m_currentRule.episodeFilter().isEmpty()) m_ui->lineEFilter->setText(m_currentRule.episodeFilter()); else m_ui->lineEFilter->clear(); - m_ui->checkBoxSaveDiffDir->setChecked(!m_currentRule.savePath().isEmpty()); - m_ui->lineSavePath->setSelectedPath(m_currentRule.savePath()); m_ui->checkRegex->blockSignals(true); m_ui->checkRegex->setChecked(m_currentRule.useRegex()); m_ui->checkRegex->blockSignals(false); m_ui->checkSmart->blockSignals(true); m_ui->checkSmart->setChecked(m_currentRule.useSmartFilter()); m_ui->checkSmart->blockSignals(false); - m_ui->comboCategory->setCurrentIndex(m_ui->comboCategory->findText(m_currentRule.assignedCategory())); - if (m_currentRule.assignedCategory().isEmpty()) - m_ui->comboCategory->clearEditText(); - int index = 0; - if (m_currentRule.addPaused().has_value()) - index = (*m_currentRule.addPaused() ? 1 : 2); - m_ui->comboAddPaused->setCurrentIndex(index); - index = 0; - if (m_currentRule.torrentContentLayout()) - index = static_cast(*m_currentRule.torrentContentLayout()) + 1; - m_ui->comboContentLayout->setCurrentIndex(index); m_ui->spinIgnorePeriod->setValue(m_currentRule.ignoreDays()); QDateTime dateTime = m_currentRule.lastMatch(); QString lMatch; @@ -307,13 +308,13 @@ void AutomatedRssDownloader::updateRuleDefinitionBox() updateEpisodeFilterValidity(); updateFieldsToolTips(m_ui->checkRegex->isChecked()); - m_ui->ruleDefBox->setEnabled(true); + m_ui->ruleScrollArea->setEnabled(true); } else { m_currentRule = RSS::AutoDownloadRule(); clearRuleDefinitionBox(); - m_ui->ruleDefBox->setEnabled(false); + m_ui->ruleScrollArea->setEnabled(false); } updateFeedList(); @@ -322,38 +323,23 @@ void AutomatedRssDownloader::updateRuleDefinitionBox() void AutomatedRssDownloader::clearRuleDefinitionBox() { + m_addTorrentParamsWidget->setAddTorrentParams({}); m_ui->lineContains->clear(); m_ui->lineNotContains->clear(); m_ui->lineEFilter->clear(); - m_ui->checkBoxSaveDiffDir->setChecked(false); - m_ui->lineSavePath->clear(); - m_ui->comboCategory->clearEditText(); - m_ui->comboCategory->setCurrentIndex(-1); m_ui->checkRegex->setChecked(false); m_ui->checkSmart->setChecked(false); m_ui->spinIgnorePeriod->setValue(0); - m_ui->comboAddPaused->clearEditText(); - m_ui->comboAddPaused->setCurrentIndex(-1); - m_ui->comboContentLayout->clearEditText(); - m_ui->comboContentLayout->setCurrentIndex(-1); updateFieldsToolTips(m_ui->checkRegex->isChecked()); updateMustLineValidity(); updateMustNotLineValidity(); updateEpisodeFilterValidity(); } -void AutomatedRssDownloader::initCategoryCombobox() -{ - // Load torrent categories - QStringList categories = BitTorrent::Session::instance()->categories(); - std::sort(categories.begin(), categories.end(), Utils::Compare::NaturalLessThan()); - m_ui->comboCategory->addItem(u""_qs); - m_ui->comboCategory->addItems(categories); -} - void AutomatedRssDownloader::updateEditedRule() { - if (!m_currentRuleItem || !m_ui->ruleDefBox->isEnabled()) return; + if (!m_currentRuleItem || !m_ui->ruleScrollArea->isEnabled()) + return; m_currentRule.setEnabled(m_currentRuleItem->checkState() != Qt::Unchecked); m_currentRule.setUseRegex(m_ui->checkRegex->isChecked()); @@ -361,32 +347,20 @@ void AutomatedRssDownloader::updateEditedRule() m_currentRule.setMustContain(m_ui->lineContains->text()); m_currentRule.setMustNotContain(m_ui->lineNotContains->text()); m_currentRule.setEpisodeFilter(m_ui->lineEFilter->text()); - m_currentRule.setSavePath(m_ui->checkBoxSaveDiffDir->isChecked() ? m_ui->lineSavePath->selectedPath() : Path()); - m_currentRule.setCategory(m_ui->comboCategory->currentText()); - std::optional addPaused; - if (m_ui->comboAddPaused->currentIndex() == 1) - addPaused = true; - else if (m_ui->comboAddPaused->currentIndex() == 2) - addPaused = false; - m_currentRule.setAddPaused(addPaused); - - std::optional contentLayout; - if (m_ui->comboContentLayout->currentIndex() > 0) - contentLayout = static_cast(m_ui->comboContentLayout->currentIndex() - 1); - m_currentRule.setTorrentContentLayout(contentLayout); - m_currentRule.setIgnoreDays(m_ui->spinIgnorePeriod->value()); + + m_currentRule.setAddTorrentParams(m_addTorrentParamsWidget->addTorrentParams()); } void AutomatedRssDownloader::saveEditedRule() { - if (!m_currentRuleItem || !m_ui->ruleDefBox->isEnabled()) return; + if (!m_currentRuleItem || !m_ui->ruleScrollArea->isEnabled()) return; updateEditedRule(); RSS::AutoDownloader::instance()->insertRule(m_currentRule); } -void AutomatedRssDownloader::on_addRuleBtn_clicked() +void AutomatedRssDownloader::onAddRuleBtnClicked() { // saveEditedRule(); @@ -406,9 +380,9 @@ void AutomatedRssDownloader::on_addRuleBtn_clicked() RSS::AutoDownloader::instance()->insertRule(RSS::AutoDownloadRule(ruleName)); } -void AutomatedRssDownloader::on_removeRuleBtn_clicked() +void AutomatedRssDownloader::onRemoveRuleBtnClicked() { - const QList selection = m_ui->listRules->selectedItems(); + const QList selection = m_ui->ruleList->selectedItems(); if (selection.isEmpty()) return; // Ask for confirmation @@ -423,23 +397,12 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked() RSS::AutoDownloader::instance()->removeRule(item->text()); } -void AutomatedRssDownloader::on_addCategoryBtn_clicked() -{ - const QString newCategoryName = TorrentCategoryDialog::createCategory(this); - - if (!newCategoryName.isEmpty()) - { - m_ui->comboCategory->addItem(newCategoryName); - m_ui->comboCategory->setCurrentText(newCategoryName); - } -} - -void AutomatedRssDownloader::on_renameRuleBtn_clicked() +void AutomatedRssDownloader::onRenameRuleBtnClicked() { renameSelectedRule(); } -void AutomatedRssDownloader::on_exportBtn_clicked() +void AutomatedRssDownloader::onExportBtnClicked() { if (RSS::AutoDownloader::instance()->rules().isEmpty()) { @@ -482,7 +445,7 @@ void AutomatedRssDownloader::on_exportBtn_clicked() } } -void AutomatedRssDownloader::on_importBtn_clicked() +void AutomatedRssDownloader::onImportBtnClicked() { QString selectedFilter {m_formatFilterJSON}; const Path path {QFileDialog::getOpenFileName( @@ -525,16 +488,16 @@ void AutomatedRssDownloader::displayRulesListMenu() menu->setAttribute(Qt::WA_DeleteOnClose); menu->addAction(UIThemeManager::instance()->getIcon(u"list-add"_qs), tr("Add new rule...") - , this, &AutomatedRssDownloader::on_addRuleBtn_clicked); + , this, &AutomatedRssDownloader::onAddRuleBtnClicked); - const QList selection = m_ui->listRules->selectedItems(); + const QList selection = m_ui->ruleList->selectedItems(); if (!selection.isEmpty()) { if (selection.count() == 1) { menu->addAction(UIThemeManager::instance()->getIcon(u"edit-clear"_qs, u"list-remove"_qs), tr("Delete rule") - , this, &AutomatedRssDownloader::on_removeRuleBtn_clicked); + , this, &AutomatedRssDownloader::onRemoveRuleBtnClicked); menu->addSeparator(); menu->addAction(UIThemeManager::instance()->getIcon(u"edit-rename"_qs), tr("Rename rule...") , this, &AutomatedRssDownloader::renameSelectedRule); @@ -542,7 +505,7 @@ void AutomatedRssDownloader::displayRulesListMenu() else { menu->addAction(UIThemeManager::instance()->getIcon(u"edit-clear"_qs, u"list-remove"_qs), tr("Delete selected rules") - , this, &AutomatedRssDownloader::on_removeRuleBtn_clicked); + , this, &AutomatedRssDownloader::onRemoveRuleBtnClicked); } menu->addSeparator(); @@ -555,7 +518,7 @@ void AutomatedRssDownloader::displayRulesListMenu() void AutomatedRssDownloader::renameSelectedRule() { - const QList selection = m_ui->listRules->selectedItems(); + const QList selection = m_ui->ruleList->selectedItems(); if (selection.isEmpty()) return; QListWidgetItem *item = selection.first(); @@ -583,7 +546,7 @@ void AutomatedRssDownloader::renameSelectedRule() void AutomatedRssDownloader::handleRuleCheckStateChange(QListWidgetItem *ruleItem) { - m_ui->listRules->setCurrentItem(ruleItem); + m_ui->ruleList->setCurrentItem(ruleItem); } void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList() @@ -604,7 +567,7 @@ void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList() void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feedItem) { const QString feedURL = feedItem->data(Qt::UserRole).toString(); - for (QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems())) + for (QListWidgetItem *ruleItem : asConst(m_ui->ruleList->selectedItems())) { RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem ? m_currentRule @@ -627,9 +590,9 @@ void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feedIte void AutomatedRssDownloader::updateMatchingArticles() { - m_ui->treeMatchingArticles->clear(); + m_ui->matchingArticlesTree->clear(); - for (const QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems())) + for (const QListWidgetItem *ruleItem : asConst(m_ui->ruleList->selectedItems())) { RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem ? m_currentRule @@ -654,13 +617,13 @@ void AutomatedRssDownloader::updateMatchingArticles() void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStringList &articles) { // Turn off sorting while inserting - m_ui->treeMatchingArticles->setSortingEnabled(false); + m_ui->matchingArticlesTree->setSortingEnabled(false); // Check if this feed is already in the tree QTreeWidgetItem *treeFeedItem = nullptr; - for (int i = 0; i < m_ui->treeMatchingArticles->topLevelItemCount(); ++i) + for (int i = 0; i < m_ui->matchingArticlesTree->topLevelItemCount(); ++i) { - QTreeWidgetItem *item = m_ui->treeMatchingArticles->topLevelItem(i); + QTreeWidgetItem *item = m_ui->matchingArticlesTree->topLevelItem(i); if (item->data(0, Qt::UserRole).toString() == feed->url()) { treeFeedItem = item; @@ -678,7 +641,7 @@ void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStrin treeFeedItem->setFont(0, f); treeFeedItem->setData(0, Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"directory"_qs)); treeFeedItem->setData(0, Qt::UserRole, feed->url()); - m_ui->treeMatchingArticles->addTopLevelItem(treeFeedItem); + m_ui->matchingArticlesTree->addTopLevelItem(treeFeedItem); } // Insert the articles @@ -695,9 +658,9 @@ void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStrin } } - m_ui->treeMatchingArticles->expandItem(treeFeedItem); - m_ui->treeMatchingArticles->sortItems(0, Qt::AscendingOrder); - m_ui->treeMatchingArticles->setSortingEnabled(true); + m_ui->matchingArticlesTree->expandItem(treeFeedItem); + m_ui->matchingArticlesTree->sortItems(0, Qt::AscendingOrder); + m_ui->matchingArticlesTree->setSortingEnabled(true); } void AutomatedRssDownloader::updateFieldsToolTips(bool regex) diff --git a/src/gui/rss/automatedrssdownloader.h b/src/gui/rss/automatedrssdownloader.h index acf588e17..7c95bcb65 100644 --- a/src/gui/rss/automatedrssdownloader.h +++ b/src/gui/rss/automatedrssdownloader.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2017 Vladimir Golovnev + * Copyright (C) 2017, 2023 Vladimir Golovnev * Copyright (C) 2010 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -51,6 +51,8 @@ namespace Ui class AutomatedRssDownloader; } +class AddTorrentParamsWidget; + class AutomatedRssDownloader : public QDialog { Q_OBJECT @@ -61,13 +63,11 @@ public: ~AutomatedRssDownloader() override; private slots: - void on_addRuleBtn_clicked(); - void on_removeRuleBtn_clicked(); - void on_addCategoryBtn_clicked(); - void on_exportBtn_clicked(); - void on_importBtn_clicked(); - void on_renameRuleBtn_clicked(); - + void onAddRuleBtnClicked(); + void onRemoveRuleBtnClicked(); + void onExportBtnClicked(); + void onImportBtnClicked(); + void onRenameRuleBtnClicked(); void handleRuleCheckStateChange(QListWidgetItem *ruleItem); void handleFeedCheckStateChange(QListWidgetItem *feedItem); void displayRulesListMenu(); @@ -90,7 +90,6 @@ private: void loadSettings(); void saveSettings(); void createRuleItem(const RSS::AutoDownloadRule &rule); - void initCategoryCombobox(); void clearRuleDefinitionBox(); void updateEditedRule(); void updateMatchingArticles(); @@ -103,6 +102,7 @@ private: const QString m_formatFilterLegacy; Ui::AutomatedRssDownloader *m_ui = nullptr; + AddTorrentParamsWidget *m_addTorrentParamsWidget = nullptr; QListWidgetItem *m_currentRuleItem = nullptr; QSet> m_treeListEntries; RSS::AutoDownloadRule m_currentRule; @@ -110,5 +110,6 @@ private: QRegularExpression *m_episodeRegex = nullptr; SettingValue m_storeDialogSize; - SettingValue m_storeHSplitterSize; + SettingValue m_storeMainSplitterState; + SettingValue m_storeRuleDefSplitterState; }; diff --git a/src/gui/rss/automatedrssdownloader.ui b/src/gui/rss/automatedrssdownloader.ui index b54ab5841..aa0792237 100644 --- a/src/gui/rss/automatedrssdownloader.ui +++ b/src/gui/rss/automatedrssdownloader.ui @@ -7,13 +7,13 @@ 0 0 818 - 571 + 588 RSS Downloader - + @@ -33,7 +33,7 @@ - + 0 @@ -43,15 +43,14 @@ Qt::Horizontal - - + + - + - + - 75 true @@ -99,7 +98,7 @@ - + Qt::CustomContextMenu @@ -107,313 +106,240 @@ - - - - - - Rule Definition - - - - - - Use Regular Expressions - - - - - - - - - Must Contain: - - - - - - - Must Not Contain: - - - - - - - Episode Filter: - - - - - - - - 18 - 18 - - - - - - - - - 18 - 18 - - - - - - - - - - - - 18 - 18 - - - - - - - - - 18 - 18 - - - - - - - - - - - - - - - - Smart Episode Filter will check the episode number to prevent downloading of duplicates. -Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also support - as a separator) - - - Use Smart Episode Filter - - - - - - - Qt::Horizontal - - - - - - - - - - 0 - 0 - - - - Category: - - - - - - - false - - - - - - - - - - - - Save to a Different Directory - - - - - - - - - false - - - Save to: - - - - - - - - - - - - - - Ignore Subsequent Matches for (0 to Disable) - - - - - - - true - - - Disabled - - - days - - - 0 - - - 365 - - - - - - - - - true - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - Add Paused: - - - - - - - - Use global settings - - - - - Always - - - - - Never - - - - - - - - - - - - - 0 - 0 - - - - Torrent content layout: - - - - - - - - Use global settings - - - - - Original - - - - - Create subfolder - - - - - Don't create subfolder - - - - - - - - - - - + + + Qt::Vertical + + + + + 0 + 0 + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAsNeeded + + + QAbstractScrollArea::AdjustToContentsOnFirstShow + + + true + + + + + 0 + 0 + 329 + 243 + + + - - - - 50 - false - - + - Apply Rule to Feeds: + Use Regular Expressions - + + + + + Must Contain: + + + + + + + Must Not Contain: + + + + + + + Episode Filter: + + + + + + + + 18 + 18 + + + + + + + + + 18 + 18 + + + + + + + + + + + + 18 + 18 + + + + + + + + + 18 + 18 + + + + + + + + + + + + + + + + Smart Episode Filter will check the episode number to prevent downloading of duplicates. +Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also support - as a separator) + + + Use Smart Episode Filter + + + + + + + + + Ignore Subsequent Matches for (0 to Disable) + + + + + + + true + + + Disabled + + + days + + + 0 + + + 365 + + + + + + + + + true + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Torrent parameters + + + true + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + - - + + + + + + QLayout::SetDefaultConstraint + + + + + + false + + + + Apply Rule to Feeds: + + + + + + + + - - + + - + - 75 true @@ -423,7 +349,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also - + false @@ -439,7 +365,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also - + @@ -474,31 +400,17 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also - - - FileSystemPathLineEdit - QWidget -
    gui/fspathedit.h
    -
    -
    renameRuleBtn removeRuleBtn addRuleBtn - listRules - checkRegex - checkSmart + ruleList lineContains lineNotContains lineEFilter - comboCategory - checkBoxSaveDiffDir - lineSavePath spinIgnorePeriod - comboAddPaused - comboContentLayout listFeeds - treeMatchingArticles + matchingArticlesTree importBtn exportBtn @@ -536,37 +448,5 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also - - checkBoxSaveDiffDir - toggled(bool) - label_6 - setEnabled(bool) - - - 304 - 171 - - - 377 - 205 - - - - - checkBoxSaveDiffDir - toggled(bool) - lineSavePath - setEnabled(bool) - - - 474 - 174 - - - 476 - 204 - - -