mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-08-20 21:33:27 -07:00
Merge 46eb984e31
into feacfb0627
This commit is contained in:
commit
f484681da0
3 changed files with 133 additions and 48 deletions
|
@ -100,6 +100,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent)
|
||||||
m_ui->mainSplitter->setCollapsible(0, false);
|
m_ui->mainSplitter->setCollapsible(0, false);
|
||||||
m_ui->mainSplitter->setCollapsible(1, false);
|
m_ui->mainSplitter->setCollapsible(1, false);
|
||||||
m_ui->mainSplitter->setCollapsible(2, true); // Only the preview list is collapsible
|
m_ui->mainSplitter->setCollapsible(2, true); // Only the preview list is collapsible
|
||||||
|
m_ui->listFeeds->setHeaderHidden(true);
|
||||||
|
|
||||||
connect(m_ui->checkRegex, &QAbstractButton::toggled, this, &AutomatedRssDownloader::updateFieldsToolTips);
|
connect(m_ui->checkRegex, &QAbstractButton::toggled, this, &AutomatedRssDownloader::updateFieldsToolTips);
|
||||||
connect(m_ui->ruleList, &QWidget::customContextMenuRequested, this, &AutomatedRssDownloader::displayRulesListMenu);
|
connect(m_ui->ruleList, &QWidget::customContextMenuRequested, this, &AutomatedRssDownloader::displayRulesListMenu);
|
||||||
|
@ -145,7 +146,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(QWidget *parent)
|
||||||
connect(m_ui->spinIgnorePeriod, qOverload<int>(&QSpinBox::valueChanged)
|
connect(m_ui->spinIgnorePeriod, qOverload<int>(&QSpinBox::valueChanged)
|
||||||
, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
|
, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
|
||||||
|
|
||||||
connect(m_ui->listFeeds, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleFeedCheckStateChange);
|
connect(m_ui->listFeeds, &QTreeWidget::itemChanged, this, &AutomatedRssDownloader::handleFeedCheckStateChange);
|
||||||
|
|
||||||
connect(m_ui->ruleList, &QListWidget::itemSelectionChanged, this, &AutomatedRssDownloader::updateRuleDefinitionBox);
|
connect(m_ui->ruleList, &QListWidget::itemSelectionChanged, this, &AutomatedRssDownloader::updateRuleDefinitionBox);
|
||||||
connect(m_ui->ruleList, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleRuleCheckStateChange);
|
connect(m_ui->ruleList, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleRuleCheckStateChange);
|
||||||
|
@ -213,17 +214,84 @@ void AutomatedRssDownloader::createRuleItem(const RSS::AutoDownloadRule &rule)
|
||||||
void AutomatedRssDownloader::loadFeedList()
|
void AutomatedRssDownloader::loadFeedList()
|
||||||
{
|
{
|
||||||
const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
|
const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
|
||||||
|
QTreeWidgetItem *rssRoot = createFeedTreeItem(RSS::Session::instance()->rootFolder(), nullptr);
|
||||||
for (const auto *feed : asConst(RSS::Session::instance()->feeds()))
|
loadFeedTree(rssRoot, RSS::Session::instance()->rootFolder());
|
||||||
{
|
|
||||||
QListWidgetItem *item = new QListWidgetItem(feed->name(), m_ui->listFeeds);
|
|
||||||
item->setData(Qt::UserRole, feed->url());
|
|
||||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFeedList();
|
updateFeedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTreeWidgetItem * AutomatedRssDownloader::createFeedTreeItem(const RSS::Item *rssItem, QTreeWidgetItem *parentItem)
|
||||||
|
{
|
||||||
|
auto *item = new QTreeWidgetItem;
|
||||||
|
item->setData(0, Qt::UserRole, QVariant::fromValue(rssItem));
|
||||||
|
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate);
|
||||||
|
item->setCheckState(0, Qt::Unchecked); // Init state for folders as we don't manually set them later
|
||||||
|
|
||||||
|
QIcon icon;
|
||||||
|
if(auto feed = qobject_cast<const RSS::Feed *>(rssItem))
|
||||||
|
{
|
||||||
|
const QPixmap pixmap{feed->iconPath().data()};
|
||||||
|
if(!pixmap.isNull())
|
||||||
|
icon = {pixmap};
|
||||||
|
else
|
||||||
|
icon = UIThemeManager::instance()->getIcon(u"application-rss"_qs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
icon = UIThemeManager::instance()->getIcon(u"directory"_qs);
|
||||||
|
}
|
||||||
|
item->setData(0, Qt::DecorationRole, icon);
|
||||||
|
|
||||||
|
if(!parentItem)
|
||||||
|
{
|
||||||
|
item->setData(0, Qt::DisplayRole, u"/"_qs);
|
||||||
|
m_ui->listFeeds->addTopLevelItem(item);
|
||||||
|
item->setExpanded(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->setData(0, Qt::DisplayRole, rssItem->name());
|
||||||
|
parentItem->addChild(item);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutomatedRssDownloader::loadFeedTree(QTreeWidgetItem *parent, const RSS::Folder *rssParent)
|
||||||
|
{
|
||||||
|
for (const auto *rssItem : asConst(rssParent->items()))
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *item = createFeedTreeItem(rssItem, parent);
|
||||||
|
|
||||||
|
// Recursive call if this is a folder.
|
||||||
|
if (const auto *folder = qobject_cast<const RSS::Folder *>(rssItem))
|
||||||
|
loadFeedTree(item, folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QTreeWidgetItem *> AutomatedRssDownloader::getAllFeedTreeItems(QTreeWidgetItem *parent) const
|
||||||
|
{
|
||||||
|
QList<QTreeWidgetItem *> feedItems;
|
||||||
|
int nbChildren = (parent ? parent->childCount() : m_ui->listFeeds->topLevelItemCount());
|
||||||
|
for (int i = 0; i < nbChildren; ++i)
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *item (parent ? parent->child(i) : m_ui->listFeeds->topLevelItem(i));
|
||||||
|
if (qobject_cast<RSS::Feed *>(item->data(0, Qt::UserRole).value<RSS::Item *>()))
|
||||||
|
feedItems << item;
|
||||||
|
else
|
||||||
|
feedItems << getAllFeedTreeItems(item);
|
||||||
|
}
|
||||||
|
return feedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutomatedRssDownloader::sortTreeRecursively(QTreeWidgetItem *item)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < item->childCount(); i++) {
|
||||||
|
QTreeWidgetItem *child = item->child(i);
|
||||||
|
sortTreeRecursively(child);
|
||||||
|
}
|
||||||
|
item->sortChildren(0, Qt::AscendingOrder);
|
||||||
|
}
|
||||||
|
|
||||||
void AutomatedRssDownloader::updateFeedList()
|
void AutomatedRssDownloader::updateFeedList()
|
||||||
{
|
{
|
||||||
const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
|
const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
|
||||||
|
@ -237,10 +305,14 @@ void AutomatedRssDownloader::updateFeedList()
|
||||||
|
|
||||||
bool enable = !selection.isEmpty();
|
bool enable = !selection.isEmpty();
|
||||||
|
|
||||||
for (int i = 0; i < m_ui->listFeeds->count(); ++i)
|
for (int i = 0; i < m_ui->listFeeds->topLevelItemCount(); ++i)
|
||||||
|
m_ui->listFeeds->topLevelItem(i)->setHidden(!enable);
|
||||||
|
|
||||||
|
for (QTreeWidgetItem* item: asConst(getAllFeedTreeItems()))
|
||||||
{
|
{
|
||||||
QListWidgetItem *item = m_ui->listFeeds->item(i);
|
if (auto rssItem = qobject_cast<const RSS::Feed *>(item->data(0, Qt::UserRole).value<RSS::Item *>()))
|
||||||
const QString feedURL = item->data(Qt::UserRole).toString();
|
{
|
||||||
|
const QString feedURL = rssItem->url();
|
||||||
item->setHidden(!enable);
|
item->setHidden(!enable);
|
||||||
|
|
||||||
bool allEnabled = true;
|
bool allEnabled = true;
|
||||||
|
@ -254,16 +326,16 @@ void AutomatedRssDownloader::updateFeedList()
|
||||||
else
|
else
|
||||||
allEnabled = false;
|
allEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyEnabled && allEnabled)
|
if (anyEnabled && allEnabled)
|
||||||
item->setCheckState(Qt::Checked);
|
item->setCheckState(0, Qt::Checked);
|
||||||
else if (anyEnabled)
|
else if (anyEnabled)
|
||||||
item->setCheckState(Qt::PartiallyChecked);
|
item->setCheckState(0, Qt::PartiallyChecked);
|
||||||
else
|
else
|
||||||
item->setCheckState(Qt::Unchecked);
|
item->setCheckState(0, Qt::Unchecked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->listFeeds->sortItems();
|
sortTreeRecursively(m_ui->listFeeds->invisibleRootItem());
|
||||||
m_ui->lblListFeeds->setEnabled(enable);
|
m_ui->lblListFeeds->setEnabled(enable);
|
||||||
m_ui->listFeeds->setEnabled(enable);
|
m_ui->listFeeds->setEnabled(enable);
|
||||||
}
|
}
|
||||||
|
@ -578,18 +650,22 @@ void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feedItem)
|
void AutomatedRssDownloader::handleFeedCheckStateChange(QTreeWidgetItem *feedItem, int column)
|
||||||
{
|
{
|
||||||
const QString feedURL = feedItem->data(Qt::UserRole).toString();
|
Q_ASSERT(column == 0);
|
||||||
|
const RSS::Item *rssItem = feedItem->data(0, Qt::UserRole).value<const RSS::Item *>();
|
||||||
|
if (auto *feed = qobject_cast<const RSS::Feed *>(rssItem))
|
||||||
|
{
|
||||||
|
const QString feedURL = feed->url();
|
||||||
for (QListWidgetItem *ruleItem : asConst(m_ui->ruleList->selectedItems()))
|
for (QListWidgetItem *ruleItem : asConst(m_ui->ruleList->selectedItems()))
|
||||||
{
|
{
|
||||||
RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
|
RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
|
||||||
? m_currentRule
|
? m_currentRule
|
||||||
: RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
|
: RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
|
||||||
QStringList affectedFeeds = rule.feedURLs();
|
QStringList affectedFeeds = rule.feedURLs();
|
||||||
if ((feedItem->checkState() == Qt::Checked) && !affectedFeeds.contains(feedURL))
|
if ((feedItem->checkState(0) == Qt::Checked) && !affectedFeeds.contains(feedURL))
|
||||||
affectedFeeds << feedURL;
|
affectedFeeds << feedURL;
|
||||||
else if ((feedItem->checkState() == Qt::Unchecked) && affectedFeeds.contains(feedURL))
|
else if ((feedItem->checkState(0) == Qt::Unchecked) && affectedFeeds.contains(feedURL))
|
||||||
affectedFeeds.removeOne(feedURL);
|
affectedFeeds.removeOne(feedURL);
|
||||||
|
|
||||||
rule.setFeedURLs(affectedFeeds);
|
rule.setFeedURLs(affectedFeeds);
|
||||||
|
@ -598,6 +674,7 @@ void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feedIte
|
||||||
else
|
else
|
||||||
m_currentRule = rule;
|
m_currentRule = rule;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleRuleDefinitionChanged();
|
handleRuleDefinitionChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,20 @@
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
#include "base/rss/rss_autodownloadrule.h"
|
#include "base/rss/rss_autodownloadrule.h"
|
||||||
#include "base/settingvalue.h"
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
class QTreeWidgetItem;
|
||||||
class QRegularExpression;
|
class QRegularExpression;
|
||||||
|
|
||||||
namespace RSS
|
namespace RSS
|
||||||
{
|
{
|
||||||
class Feed;
|
class Feed;
|
||||||
|
class Folder;
|
||||||
|
class Item;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
|
@ -69,7 +73,7 @@ private slots:
|
||||||
void onImportBtnClicked();
|
void onImportBtnClicked();
|
||||||
void onRenameRuleBtnClicked();
|
void onRenameRuleBtnClicked();
|
||||||
void handleRuleCheckStateChange(QListWidgetItem *ruleItem);
|
void handleRuleCheckStateChange(QListWidgetItem *ruleItem);
|
||||||
void handleFeedCheckStateChange(QListWidgetItem *feedItem);
|
void handleFeedCheckStateChange(QTreeWidgetItem *feedItem, int column);
|
||||||
void displayRulesListMenu();
|
void displayRulesListMenu();
|
||||||
void renameSelectedRule();
|
void renameSelectedRule();
|
||||||
void updateRuleDefinitionBox();
|
void updateRuleDefinitionBox();
|
||||||
|
@ -95,6 +99,10 @@ private:
|
||||||
void updateMatchingArticles();
|
void updateMatchingArticles();
|
||||||
void saveEditedRule();
|
void saveEditedRule();
|
||||||
void loadFeedList();
|
void loadFeedList();
|
||||||
|
QTreeWidgetItem *createFeedTreeItem(const RSS::Item *rssItem, QTreeWidgetItem *parentItem);
|
||||||
|
QList<QTreeWidgetItem *>getAllFeedTreeItems(QTreeWidgetItem *parent = nullptr) const;
|
||||||
|
void loadFeedTree(QTreeWidgetItem *parent, const RSS::Folder *rssParent);
|
||||||
|
void sortTreeRecursively(QTreeWidgetItem *item);
|
||||||
void updateFeedList();
|
void updateFeedList();
|
||||||
void addFeedArticlesToTree(RSS::Feed *feed, const QStringList &articles);
|
void addFeedArticlesToTree(RSS::Feed *feed, const QStringList &articles);
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ Supports the formats: S01E01, 1x1, 2017.12.31 and 31.12.2017 (Date formats also
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListWidget" name="listFeeds"/>
|
<widget class="QTreeWidget" name="listFeeds"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue