qBittorrent
AutomatedRssDownloader Class Reference

#include <automatedrssdownloader.h>

Inheritance diagram for AutomatedRssDownloader:
Collaboration diagram for AutomatedRssDownloader:

Public Member Functions

 AutomatedRssDownloader (QWidget *parent=nullptr)
 
 ~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 handleRuleCheckStateChange (QListWidgetItem *ruleItem)
 
void handleFeedCheckStateChange (QListWidgetItem *feedItem)
 
void displayRulesListMenu ()
 
void renameSelectedRule ()
 
void updateRuleDefinitionBox ()
 
void clearSelectedRuleDownloadedEpisodeList ()
 
void updateFieldsToolTips (bool regex)
 
void updateMustLineValidity ()
 
void updateMustNotLineValidity ()
 
void updateEpisodeFilterValidity ()
 
void handleRuleDefinitionChanged ()
 
void handleRuleAdded (const QString &ruleName)
 
void handleRuleRenamed (const QString &ruleName, const QString &oldRuleName)
 
void handleRuleChanged (const QString &ruleName)
 
void handleRuleAboutToBeRemoved (const QString &ruleName)
 
void handleProcessingStateChanged (bool enabled)
 

Private Member Functions

void loadSettings ()
 
void saveSettings ()
 
void createRuleItem (const RSS::AutoDownloadRule &rule)
 
void initCategoryCombobox ()
 
void clearRuleDefinitionBox ()
 
void updateEditedRule ()
 
void updateMatchingArticles ()
 
void saveEditedRule ()
 
void loadFeedList ()
 
void updateFeedList ()
 
void addFeedArticlesToTree (RSS::Feed *feed, const QStringList &articles)
 

Private Attributes

const QString m_formatFilterJSON
 
const QString m_formatFilterLegacy
 
Ui::AutomatedRssDownloader * m_ui
 
QListWidgetItem * m_currentRuleItem
 
QSet< std::pair< QString, QString > > m_treeListEntries
 
RSS::AutoDownloadRule m_currentRule
 
QHash< QString, QListWidgetItem * > m_itemsByRuleName
 
QRegularExpression * m_episodeRegex
 

Detailed Description

Definition at line 53 of file automatedrssdownloader.h.

Constructor & Destructor Documentation

◆ AutomatedRssDownloader()

AutomatedRssDownloader::AutomatedRssDownloader ( QWidget *  parent = nullptr)
explicit

Definition at line 62 of file automatedrssdownloader.cpp.

63  : QDialog(parent)
64  , m_formatFilterJSON(QString::fromLatin1("%1 (*%2)").arg(tr("Rules"), EXT_JSON))
65  , m_formatFilterLegacy(QString::fromLatin1("%1 (*%2)").arg(tr("Rules (legacy)"), EXT_LEGACY))
66  , m_ui(new Ui::AutomatedRssDownloader)
67  , m_currentRuleItem(nullptr)
68 {
69  m_ui->setupUi(this);
70  // Icons
71  m_ui->removeRuleBtn->setIcon(UIThemeManager::instance()->getIcon("list-remove"));
72  m_ui->addRuleBtn->setIcon(UIThemeManager::instance()->getIcon("list-add"));
73  m_ui->addCategoryBtn->setIcon(UIThemeManager::instance()->getIcon("list-add"));
74 
75  // Ui Settings
76  m_ui->listRules->setSortingEnabled(true);
77  m_ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection);
78  m_ui->treeMatchingArticles->setSortingEnabled(true);
79  m_ui->treeMatchingArticles->sortByColumn(0, Qt::AscendingOrder);
80  m_ui->hsplitter->setCollapsible(0, false);
81  m_ui->hsplitter->setCollapsible(1, false);
82  m_ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible
83  m_ui->lineSavePath->setDialogCaption(tr("Destination directory"));
84  m_ui->lineSavePath->setMode(FileSystemPathEdit::Mode::DirectorySave);
85 
86  connect(m_ui->checkRegex, &QAbstractButton::toggled, this, &AutomatedRssDownloader::updateFieldsToolTips);
87  connect(m_ui->listRules, &QWidget::customContextMenuRequested, this, &AutomatedRssDownloader::displayRulesListMenu);
88 
89  m_episodeRegex = new QRegularExpression("^(^\\d{1,4}x(\\d{1,4}(-(\\d{1,4})?)?;){1,}){1,1}"
90  , QRegularExpression::CaseInsensitiveOption);
91  QString tip = "<p>" + tr("Matches articles based on episode filter.") + "</p><p><b>" + tr("Example: ")
92  + "1x2;8-15;5;30-;</b>" + tr(" will match 2, 5, 8 through 15, 30 and onward episodes of season one", "example X will match") + "</p>";
93  tip += "<p>" + tr("Episode filter rules: ") + "</p><ul><li>" + tr("Season number is a mandatory non-zero value") + "</li>"
94  + "<li>" + tr("Episode number is a mandatory positive value") + "</li>"
95  + "<li>" + tr("Filter must end with semicolon") + "</li>"
96  + "<li>" + tr("Three range types for episodes are supported: ") + "</li>" + "<li><ul>"
97  + "<li>" + tr("Single number: <b>1x25;</b> matches episode 25 of season one") + "</li>"
98  + "<li>" + tr("Normal range: <b>1x25-40;</b> matches episodes 25 through 40 of season one") + "</li>"
99  + "<li>" + tr("Infinite range: <b>1x25-;</b> matches episodes 25 and upward of season one, and all episodes of later seasons") + "</li>" + "</ul></li></ul>";
100  m_ui->lineEFilter->setToolTip(tip);
101 
103  loadSettings();
104 
109 
110  // Update matching articles when necessary
111  connect(m_ui->lineContains, &QLineEdit::textEdited, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
112  connect(m_ui->lineContains, &QLineEdit::textEdited, this, &AutomatedRssDownloader::updateMustLineValidity);
113  connect(m_ui->lineNotContains, &QLineEdit::textEdited, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
114  connect(m_ui->lineNotContains, &QLineEdit::textEdited, this, &AutomatedRssDownloader::updateMustNotLineValidity);
115  connect(m_ui->lineEFilter, &QLineEdit::textEdited, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
116  connect(m_ui->lineEFilter, &QLineEdit::textEdited, this, &AutomatedRssDownloader::updateEpisodeFilterValidity);
117  connect(m_ui->checkRegex, &QCheckBox::stateChanged, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
118  connect(m_ui->checkRegex, &QCheckBox::stateChanged, this, &AutomatedRssDownloader::updateMustLineValidity);
119  connect(m_ui->checkRegex, &QCheckBox::stateChanged, this, &AutomatedRssDownloader::updateMustNotLineValidity);
120  connect(m_ui->checkSmart, &QCheckBox::stateChanged, this, &AutomatedRssDownloader::handleRuleDefinitionChanged);
121  connect(m_ui->spinIgnorePeriod, qOverload<int>(&QSpinBox::valueChanged)
123 
124  connect(m_ui->listFeeds, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleFeedCheckStateChange);
125 
126  connect(m_ui->listRules, &QListWidget::itemSelectionChanged, this, &AutomatedRssDownloader::updateRuleDefinitionBox);
127  connect(m_ui->listRules, &QListWidget::itemChanged, this, &AutomatedRssDownloader::handleRuleCheckStateChange);
128 
129  const auto *editHotkey = new QShortcut(Qt::Key_F2, m_ui->listRules, nullptr, nullptr, Qt::WidgetShortcut);
130  connect(editHotkey, &QShortcut::activated, this, &AutomatedRssDownloader::renameSelectedRule);
131  const auto *deleteHotkey = new QShortcut(QKeySequence::Delete, m_ui->listRules, nullptr, nullptr, Qt::WidgetShortcut);
132  connect(deleteHotkey, &QShortcut::activated, this, &AutomatedRssDownloader::on_removeRuleBtn_clicked);
133 
134  connect(m_ui->listRules, &QAbstractItemView::doubleClicked, this, &AutomatedRssDownloader::renameSelectedRule);
135 
136  loadFeedList();
137 
138  m_ui->listRules->blockSignals(true);
139  for (const RSS::AutoDownloadRule &rule : asConst(RSS::AutoDownloader::instance()->rules()))
140  createRuleItem(rule);
141  m_ui->listRules->blockSignals(false);
142 
144 
145  if (RSS::AutoDownloader::instance()->isProcessingEnabled())
146  m_ui->labelWarn->hide();
149 }
const QString EXT_JSON
const QString EXT_LEGACY
QRegularExpression * m_episodeRegex
void handleProcessingStateChanged(bool enabled)
void handleRuleRenamed(const QString &ruleName, const QString &oldRuleName)
void handleFeedCheckStateChange(QListWidgetItem *feedItem)
QListWidgetItem * m_currentRuleItem
void handleRuleAboutToBeRemoved(const QString &ruleName)
void handleRuleCheckStateChange(QListWidgetItem *ruleItem)
void handleRuleAdded(const QString &ruleName)
Ui::AutomatedRssDownloader * m_ui
void createRuleItem(const RSS::AutoDownloadRule &rule)
void handleRuleChanged(const QString &ruleName)
@ DirectorySave
selecting directories for saving
void ruleChanged(const QString &ruleName)
void processingStateChanged(bool enabled)
static AutoDownloader * instance()
void ruleAdded(const QString &ruleName)
void ruleAboutToBeRemoved(const QString &ruleName)
void ruleRenamed(const QString &ruleName, const QString &oldRuleName)
static UIThemeManager * instance()
constexpr std::add_const_t< T > & asConst(T &t) noexcept
Definition: global.h:42

References asConst(), createRuleItem(), FileSystemPathEdit::DirectorySave, displayRulesListMenu(), handleFeedCheckStateChange(), handleProcessingStateChanged(), handleRuleAboutToBeRemoved(), handleRuleAdded(), handleRuleChanged(), handleRuleCheckStateChange(), handleRuleDefinitionChanged(), handleRuleRenamed(), initCategoryCombobox(), RSS::AutoDownloader::instance(), UIThemeManager::instance(), loadFeedList(), loadSettings(), m_episodeRegex, m_ui, on_removeRuleBtn_clicked(), RSS::AutoDownloader::processingStateChanged(), renameSelectedRule(), RSS::AutoDownloader::ruleAboutToBeRemoved(), RSS::AutoDownloader::ruleAdded(), RSS::AutoDownloader::ruleChanged(), RSS::AutoDownloader::ruleRenamed(), updateEpisodeFilterValidity(), updateFieldsToolTips(), updateMustLineValidity(), updateMustNotLineValidity(), and updateRuleDefinitionBox().

Here is the call graph for this function:

◆ ~AutomatedRssDownloader()

AutomatedRssDownloader::~AutomatedRssDownloader ( )
override

Definition at line 151 of file automatedrssdownloader.cpp.

152 {
153  // Save current item on exit
154  saveEditedRule();
155  saveSettings();
156 
157  delete m_ui;
158  delete m_episodeRegex;
159 }

References m_episodeRegex, m_ui, saveEditedRule(), and saveSettings().

Here is the call graph for this function:

Member Function Documentation

◆ addFeedArticlesToTree()

void AutomatedRssDownloader::addFeedArticlesToTree ( RSS::Feed feed,
const QStringList &  articles 
)
private

Definition at line 633 of file automatedrssdownloader.cpp.

634 {
635  // Turn off sorting while inserting
636  m_ui->treeMatchingArticles->setSortingEnabled(false);
637 
638  // Check if this feed is already in the tree
639  QTreeWidgetItem *treeFeedItem = nullptr;
640  for (int i = 0; i < m_ui->treeMatchingArticles->topLevelItemCount(); ++i)
641  {
642  QTreeWidgetItem *item = m_ui->treeMatchingArticles->topLevelItem(i);
643  if (item->data(0, Qt::UserRole).toString() == feed->url())
644  {
645  treeFeedItem = item;
646  break;
647  }
648  }
649 
650  // If there is none, create it
651  if (!treeFeedItem)
652  {
653  treeFeedItem = new QTreeWidgetItem(QStringList() << feed->name());
654  treeFeedItem->setToolTip(0, feed->name());
655  QFont f = treeFeedItem->font(0);
656  f.setBold(true);
657  treeFeedItem->setFont(0, f);
658  treeFeedItem->setData(0, Qt::DecorationRole, UIThemeManager::instance()->getIcon("inode-directory"));
659  treeFeedItem->setData(0, Qt::UserRole, feed->url());
660  m_ui->treeMatchingArticles->addTopLevelItem(treeFeedItem);
661  }
662 
663  // Insert the articles
664  for (const QString &article : articles)
665  {
666  const std::pair<QString, QString> key(feed->name(), article);
667 
668  if (!m_treeListEntries.contains(key))
669  {
670  m_treeListEntries << key;
671  QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << article);
672  item->setToolTip(0, article);
673  treeFeedItem->addChild(item);
674  }
675  }
676 
677  m_ui->treeMatchingArticles->expandItem(treeFeedItem);
678  m_ui->treeMatchingArticles->sortItems(0, Qt::AscendingOrder);
679  m_ui->treeMatchingArticles->setSortingEnabled(true);
680 }
QSet< std::pair< QString, QString > > m_treeListEntries
QString url() const
Definition: rss_feed.cpp:154
QString name() const
Definition: rss_item.cpp:62
void f()
Definition: test2.c:1

References f(), UIThemeManager::instance(), m_treeListEntries, m_ui, RSS::Item::name(), and RSS::Feed::url().

Referenced by updateMatchingArticles().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clearRuleDefinitionBox()

void AutomatedRssDownloader::clearRuleDefinitionBox ( )
private

Definition at line 308 of file automatedrssdownloader.cpp.

309 {
310  m_ui->lineContains->clear();
311  m_ui->lineNotContains->clear();
312  m_ui->lineEFilter->clear();
313  m_ui->checkBoxSaveDiffDir->setChecked(false);
314  m_ui->lineSavePath->clear();
315  m_ui->comboCategory->clearEditText();
316  m_ui->comboCategory->setCurrentIndex(-1);
317  m_ui->checkRegex->setChecked(false);
318  m_ui->checkSmart->setChecked(false);
319  m_ui->spinIgnorePeriod->setValue(0);
320  m_ui->comboAddPaused->clearEditText();
321  m_ui->comboAddPaused->setCurrentIndex(-1);
322  m_ui->comboContentLayout->clearEditText();
323  m_ui->comboContentLayout->setCurrentIndex(-1);
324  updateFieldsToolTips(m_ui->checkRegex->isChecked());
328 }

References m_ui, updateEpisodeFilterValidity(), updateFieldsToolTips(), updateMustLineValidity(), and updateMustNotLineValidity().

Referenced by updateRuleDefinitionBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clearSelectedRuleDownloadedEpisodeList

void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList ( )
privateslot

Definition at line 568 of file automatedrssdownloader.cpp.

569 {
570  const QMessageBox::StandardButton reply = QMessageBox::question(
571  this,
572  tr("Clear downloaded episodes"),
573  tr("Are you sure you want to clear the list of downloaded episodes for the selected rule?"),
574  QMessageBox::Yes | QMessageBox::No);
575 
576  if (reply == QMessageBox::Yes)
577  {
580  }
581 }
RSS::AutoDownloadRule m_currentRule
void setPreviouslyMatchedEpisodes(const QStringList &previouslyMatchedEpisodes)

References handleRuleDefinitionChanged(), m_currentRule, and RSS::AutoDownloadRule::setPreviouslyMatchedEpisodes().

Referenced by displayRulesListMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createRuleItem()

void AutomatedRssDownloader::createRuleItem ( const RSS::AutoDownloadRule rule)
private

Definition at line 175 of file automatedrssdownloader.cpp.

176 {
177  QListWidgetItem *item = new QListWidgetItem(rule.name(), m_ui->listRules);
178  m_itemsByRuleName.insert(rule.name(), item);
179  item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
180  item->setCheckState(rule.isEnabled() ? Qt::Checked : Qt::Unchecked);
181 }
QHash< QString, QListWidgetItem * > m_itemsByRuleName

References RSS::AutoDownloadRule::isEnabled(), m_itemsByRuleName, m_ui, and RSS::AutoDownloadRule::name().

Referenced by AutomatedRssDownloader(), and handleRuleAdded().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ displayRulesListMenu

void AutomatedRssDownloader::displayRulesListMenu ( )
privateslot

Definition at line 501 of file automatedrssdownloader.cpp.

502 {
503  QMenu *menu = new QMenu(this);
504  menu->setAttribute(Qt::WA_DeleteOnClose);
505 
506  menu->addAction(UIThemeManager::instance()->getIcon("list-add"), tr("Add new rule...")
508 
509  const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
510 
511  if (!selection.isEmpty())
512  {
513  if (selection.count() == 1)
514  {
515  menu->addAction(UIThemeManager::instance()->getIcon("list-remove"), tr("Delete rule")
517  menu->addSeparator();
518  menu->addAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename rule...")
520  }
521  else
522  {
523  menu->addAction(UIThemeManager::instance()->getIcon("list-remove"), tr("Delete selected rules")
525  }
526 
527  menu->addSeparator();
528  menu->addAction(UIThemeManager::instance()->getIcon("edit-clear"), tr("Clear downloaded episodes...")
530  }
531 
532  menu->popup(QCursor::pos());
533 }

References clearSelectedRuleDownloadedEpisodeList(), UIThemeManager::instance(), m_ui, on_addRuleBtn_clicked(), on_removeRuleBtn_clicked(), and renameSelectedRule().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleFeedCheckStateChange

void AutomatedRssDownloader::handleFeedCheckStateChange ( QListWidgetItem *  feedItem)
privateslot

Definition at line 583 of file automatedrssdownloader.cpp.

584 {
585  const QString feedURL = feedItem->data(Qt::UserRole).toString();
586  for (QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems()))
587  {
588  RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
589  ? m_currentRule
590  : RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
591  QStringList affectedFeeds = rule.feedURLs();
592  if ((feedItem->checkState() == Qt::Checked) && !affectedFeeds.contains(feedURL))
593  affectedFeeds << feedURL;
594  else if ((feedItem->checkState() == Qt::Unchecked) && affectedFeeds.contains(feedURL))
595  affectedFeeds.removeOne(feedURL);
596 
597  rule.setFeedURLs(affectedFeeds);
598  if (ruleItem != m_currentRuleItem)
600  else
601  m_currentRule = rule;
602  }
603 
605 }
void setFeedURLs(const QStringList &urls)
QStringList feedURLs() const
AutoDownloadRule ruleByName(const QString &ruleName) const
void insertRule(const AutoDownloadRule &rule)

References asConst(), RSS::AutoDownloadRule::feedURLs(), handleRuleDefinitionChanged(), RSS::AutoDownloader::insertRule(), RSS::AutoDownloader::instance(), m_currentRule, m_currentRuleItem, m_ui, RSS::AutoDownloader::ruleByName(), and RSS::AutoDownloadRule::setFeedURLs().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleProcessingStateChanged

void AutomatedRssDownloader::handleProcessingStateChanged ( bool  enabled)
privateslot

Definition at line 855 of file automatedrssdownloader.cpp.

856 {
857  m_ui->labelWarn->setVisible(!enabled);
858 }

References m_ui.

Referenced by AutomatedRssDownloader().

Here is the caller graph for this function:

◆ handleRuleAboutToBeRemoved

void AutomatedRssDownloader::handleRuleAboutToBeRemoved ( const QString &  ruleName)
privateslot

Definition at line 849 of file automatedrssdownloader.cpp.

850 {
851  m_currentRuleItem = nullptr;
852  delete m_itemsByRuleName.take(ruleName);
853 }

References m_currentRuleItem, and m_itemsByRuleName.

Referenced by AutomatedRssDownloader().

Here is the caller graph for this function:

◆ handleRuleAdded

void AutomatedRssDownloader::handleRuleAdded ( const QString &  ruleName)
privateslot

Definition at line 828 of file automatedrssdownloader.cpp.

829 {
831 }

References createRuleItem().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleRuleChanged

void AutomatedRssDownloader::handleRuleChanged ( const QString &  ruleName)
privateslot

Definition at line 842 of file automatedrssdownloader.cpp.

843 {
844  auto item = m_itemsByRuleName.value(ruleName);
845  if (item && (item != m_currentRuleItem))
846  item->setCheckState(RSS::AutoDownloader::instance()->ruleByName(ruleName).isEnabled() ? Qt::Checked : Qt::Unchecked);
847 }

References RSS::AutoDownloader::instance(), m_currentRuleItem, and m_itemsByRuleName.

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleRuleCheckStateChange

void AutomatedRssDownloader::handleRuleCheckStateChange ( QListWidgetItem *  ruleItem)
privateslot

Definition at line 563 of file automatedrssdownloader.cpp.

564 {
565  m_ui->listRules->setCurrentItem(ruleItem);
566 }

References m_ui.

Referenced by AutomatedRssDownloader().

Here is the caller graph for this function:

◆ handleRuleDefinitionChanged

void AutomatedRssDownloader::handleRuleDefinitionChanged ( )
privateslot

Definition at line 822 of file automatedrssdownloader.cpp.

References updateEditedRule(), and updateMatchingArticles().

Referenced by AutomatedRssDownloader(), clearSelectedRuleDownloadedEpisodeList(), and handleFeedCheckStateChange().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleRuleRenamed

void AutomatedRssDownloader::handleRuleRenamed ( const QString &  ruleName,
const QString &  oldRuleName 
)
privateslot

Definition at line 833 of file automatedrssdownloader.cpp.

834 {
835  auto item = m_itemsByRuleName.take(oldRuleName);
836  m_itemsByRuleName.insert(ruleName, item);
837  if (m_currentRule.name() == oldRuleName)
838  m_currentRule.setName(ruleName);
839  item->setText(ruleName);
840 }
void setName(const QString &name)

References m_currentRule, m_itemsByRuleName, RSS::AutoDownloadRule::name(), and RSS::AutoDownloadRule::setName().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initCategoryCombobox()

void AutomatedRssDownloader::initCategoryCombobox ( )
private

Definition at line 330 of file automatedrssdownloader.cpp.

331 {
332  // Load torrent categories
333  QStringList categories = BitTorrent::Session::instance()->categories();
334  std::sort(categories.begin(), categories.end(), Utils::Compare::NaturalLessThan<Qt::CaseInsensitive>());
335  m_ui->comboCategory->addItem("");
336  m_ui->comboCategory->addItems(categories);
337 }
static Session * instance()
Definition: session.cpp:997
QStringList categories() const
Definition: session.cpp:659

References BitTorrent::Session::categories(), BitTorrent::Session::instance(), and m_ui.

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadFeedList()

void AutomatedRssDownloader::loadFeedList ( )
private

Definition at line 183 of file automatedrssdownloader.cpp.

184 {
185  const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
186 
187  for (const auto feed : asConst(RSS::Session::instance()->feeds()))
188  {
189  QListWidgetItem *item = new QListWidgetItem(feed->name(), m_ui->listFeeds);
190  item->setData(Qt::UserRole, feed->url());
191  item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate);
192  }
193 
194  updateFeedList();
195 }
static Session * instance()

References asConst(), RSS::Session::instance(), m_ui, and updateFeedList().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadSettings()

void AutomatedRssDownloader::loadSettings ( )
private

Definition at line 161 of file automatedrssdownloader.cpp.

162 {
163  const Preferences *const pref = Preferences::instance();
164  Utils::Gui::resize(this, pref->getRssGeometrySize());
165  m_ui->hsplitter->restoreState(pref->getRssHSplitterSizes());
166 }
static Preferences * instance()
QSize getRssGeometrySize() const
QByteArray getRssHSplitterSizes() const
void resize(QWidget *widget, const QSize &newSize={})
Definition: utils.cpp:54

References Preferences::getRssGeometrySize(), Preferences::getRssHSplitterSizes(), Preferences::instance(), m_ui, and Utils::Gui::resize().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_addCategoryBtn_clicked

void AutomatedRssDownloader::on_addCategoryBtn_clicked ( )
privateslot

Definition at line 411 of file automatedrssdownloader.cpp.

412 {
413  const QString newCategoryName = TorrentCategoryDialog::createCategory(this);
414 
415  if (!newCategoryName.isEmpty())
416  {
417  m_ui->comboCategory->addItem(newCategoryName);
418  m_ui->comboCategory->setCurrentText(newCategoryName);
419  }
420 }
static QString createCategory(QWidget *parent, const QString &parentCategoryName={})

References TorrentCategoryDialog::createCategory(), and m_ui.

Here is the call graph for this function:

◆ on_addRuleBtn_clicked

void AutomatedRssDownloader::on_addRuleBtn_clicked ( )
privateslot

Definition at line 374 of file automatedrssdownloader.cpp.

375 {
376 // saveEditedRule();
377 
378  // Ask for a rule name
379  const QString ruleName = AutoExpandableDialog::getText(
380  this, tr("New rule name"), tr("Please type the name of the new download rule."));
381  if (ruleName.isEmpty()) return;
382 
383  // Check if this rule name already exists
384  if (RSS::AutoDownloader::instance()->hasRule(ruleName))
385  {
386  QMessageBox::warning(this, tr("Rule name conflict")
387  , tr("A rule with this name already exists, please choose another name."));
388  return;
389  }
390 
392 }
static QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode=QLineEdit::Normal, const QString &text={}, bool *ok=nullptr, bool excludeExtension=false, Qt::InputMethodHints inputMethodHints=Qt::ImhNone)

References AutoExpandableDialog::getText(), RSS::AutoDownloader::insertRule(), and RSS::AutoDownloader::instance().

Referenced by displayRulesListMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_exportBtn_clicked

void AutomatedRssDownloader::on_exportBtn_clicked ( )
privateslot

Definition at line 422 of file automatedrssdownloader.cpp.

423 {
424  if (RSS::AutoDownloader::instance()->rules().isEmpty())
425  {
426  QMessageBox::warning(this, tr("Invalid action")
427  , tr("The list is empty, there is nothing to export."));
428  return;
429  }
430 
431  QString selectedFilter {m_formatFilterJSON};
432  QString path = QFileDialog::getSaveFileName(
433  this, tr("Export RSS rules"), QDir::homePath()
434  , QString::fromLatin1("%1;;%2").arg(m_formatFilterJSON, m_formatFilterLegacy), &selectedFilter);
435  if (path.isEmpty()) return;
436 
438  {
439  (selectedFilter == m_formatFilterJSON)
442  };
443 
445  {
446  if (!path.endsWith(EXT_JSON, Qt::CaseInsensitive))
447  path += EXT_JSON;
448  }
449  else
450  {
451  if (!path.endsWith(EXT_LEGACY, Qt::CaseInsensitive))
452  path += EXT_LEGACY;
453  }
454 
455  const QByteArray rules = RSS::AutoDownloader::instance()->exportRules(format);
456  const nonstd::expected<void, QString> result = Utils::IO::saveToFile(path, rules);
457  if (!result)
458  {
459  QMessageBox::critical(this, tr("I/O Error")
460  , tr("Failed to create the destination file. Reason: %1").arg(result.error()));
461  }
462 }
QByteArray exportRules(RulesFileFormat format=RulesFileFormat::JSON) const
nonstd::expected< void, QString > saveToFile(const QString &path, const QByteArray &data)
Definition: io.cpp:69

References RSS::AutoDownloader::exportRules(), EXT_JSON, EXT_LEGACY, RSS::AutoDownloader::instance(), RSS::AutoDownloader::JSON, RSS::AutoDownloader::Legacy, m_formatFilterJSON, m_formatFilterLegacy, and Utils::IO::saveToFile().

Here is the call graph for this function:

◆ on_importBtn_clicked

void AutomatedRssDownloader::on_importBtn_clicked ( )
privateslot

Definition at line 464 of file automatedrssdownloader.cpp.

465 {
466  QString selectedFilter {m_formatFilterJSON};
467  QString path = QFileDialog::getOpenFileName(
468  this, tr("Import RSS rules"), QDir::homePath()
469  , QString::fromLatin1("%1;;%2").arg(m_formatFilterJSON, m_formatFilterLegacy), &selectedFilter);
470  if (path.isEmpty() || !QFile::exists(path))
471  return;
472 
473  QFile file {path};
474  if (!file.open(QIODevice::ReadOnly))
475  {
476  QMessageBox::critical(
477  this, tr("I/O Error")
478  , tr("Failed to open the file. Reason: %1").arg(file.errorString()));
479  return;
480  }
481 
483  {
484  (selectedFilter == m_formatFilterJSON)
487  };
488 
489  try
490  {
491  RSS::AutoDownloader::instance()->importRules(file.readAll(),format);
492  }
493  catch (const RSS::ParsingError &error)
494  {
495  QMessageBox::critical(
496  this, tr("Import Error")
497  , tr("Failed to import the selected rules file. Reason: %1").arg(error.message()));
498  }
499 }
QString message() const noexcept
Definition: exceptions.cpp:36
void importRules(const QByteArray &data, RulesFileFormat format=RulesFileFormat::JSON)
file(GLOB QBT_TS_FILES "${qBittorrent_SOURCE_DIR}/src/lang/*.ts") set_source_files_properties($
Definition: CMakeLists.txt:5

References file(), RSS::AutoDownloader::importRules(), RSS::AutoDownloader::instance(), RSS::AutoDownloader::JSON, RSS::AutoDownloader::Legacy, m_formatFilterJSON, m_formatFilterLegacy, and Exception::message().

Here is the call graph for this function:

◆ on_removeRuleBtn_clicked

void AutomatedRssDownloader::on_removeRuleBtn_clicked ( )
privateslot

Definition at line 394 of file automatedrssdownloader.cpp.

395 {
396  const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
397  if (selection.isEmpty()) return;
398 
399  // Ask for confirmation
400  const QString confirmText = ((selection.count() == 1)
401  ? tr("Are you sure you want to remove the download rule named '%1'?")
402  .arg(selection.first()->text())
403  : tr("Are you sure you want to remove the selected download rules?"));
404  if (QMessageBox::question(this, tr("Rule deletion confirmation"), confirmText, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
405  return;
406 
407  for (const QListWidgetItem *item : selection)
408  RSS::AutoDownloader::instance()->removeRule(item->text());
409 }
void removeRule(const QString &ruleName)

References RSS::AutoDownloader::instance(), m_ui, and RSS::AutoDownloader::removeRule().

Referenced by AutomatedRssDownloader(), and displayRulesListMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ renameSelectedRule

void AutomatedRssDownloader::renameSelectedRule ( )
privateslot

Definition at line 535 of file automatedrssdownloader.cpp.

536 {
537  const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
538  if (selection.isEmpty()) return;
539 
540  QListWidgetItem *item = selection.first();
541  forever
542  {
543  QString newName = AutoExpandableDialog::getText(
544  this, tr("Rule renaming"), tr("Please type the new rule name")
545  , QLineEdit::Normal, item->text());
546  newName = newName.trimmed();
547  if (newName.isEmpty()) return;
548 
549  if (RSS::AutoDownloader::instance()->hasRule(newName))
550  {
551  QMessageBox::warning(this, tr("Rule name conflict")
552  , tr("A rule with this name already exists, please choose another name."));
553  }
554  else
555  {
556  // Rename the rule
557  RSS::AutoDownloader::instance()->renameRule(item->text(), newName);
558  return;
559  }
560  }
561 }
bool renameRule(const QString &ruleName, const QString &newRuleName)

References AutoExpandableDialog::getText(), RSS::AutoDownloader::instance(), m_ui, and RSS::AutoDownloader::renameRule().

Referenced by AutomatedRssDownloader(), and displayRulesListMenu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveEditedRule()

void AutomatedRssDownloader::saveEditedRule ( )
private

Definition at line 366 of file automatedrssdownloader.cpp.

367 {
368  if (!m_currentRuleItem || !m_ui->ruleDefBox->isEnabled()) return;
369 
372 }

References RSS::AutoDownloader::insertRule(), RSS::AutoDownloader::instance(), m_currentRule, m_currentRuleItem, m_ui, and updateEditedRule().

Referenced by updateRuleDefinitionBox(), and ~AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ saveSettings()

void AutomatedRssDownloader::saveSettings ( )
private

Definition at line 168 of file automatedrssdownloader.cpp.

169 {
170  Preferences *const pref = Preferences::instance();
171  pref->setRssGeometrySize(size());
172  pref->setRssHSplitterSizes(m_ui->hsplitter->saveState());
173 }
void setRssGeometrySize(const QSize &geometry)
void setRssHSplitterSizes(const QByteArray &sizes)

References Preferences::instance(), m_ui, Preferences::setRssGeometrySize(), and Preferences::setRssHSplitterSizes().

Referenced by ~AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateEditedRule()

void AutomatedRssDownloader::updateEditedRule ( )
private

Definition at line 339 of file automatedrssdownloader.cpp.

340 {
341  if (!m_currentRuleItem || !m_ui->ruleDefBox->isEnabled()) return;
342 
343  m_currentRule.setEnabled(m_currentRuleItem->checkState() != Qt::Unchecked);
344  m_currentRule.setUseRegex(m_ui->checkRegex->isChecked());
345  m_currentRule.setUseSmartFilter(m_ui->checkSmart->isChecked());
346  m_currentRule.setMustContain(m_ui->lineContains->text());
347  m_currentRule.setMustNotContain(m_ui->lineNotContains->text());
348  m_currentRule.setEpisodeFilter(m_ui->lineEFilter->text());
349  m_currentRule.setSavePath(m_ui->checkBoxSaveDiffDir->isChecked() ? m_ui->lineSavePath->selectedPath() : "");
350  m_currentRule.setCategory(m_ui->comboCategory->currentText());
351  std::optional<bool> addPaused;
352  if (m_ui->comboAddPaused->currentIndex() == 1)
353  addPaused = true;
354  else if (m_ui->comboAddPaused->currentIndex() == 2)
355  addPaused = false;
356  m_currentRule.setAddPaused(addPaused);
357 
358  std::optional<BitTorrent::TorrentContentLayout> contentLayout;
359  if (m_ui->comboContentLayout->currentIndex() > 0)
360  contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->comboContentLayout->currentIndex() - 1);
361  m_currentRule.setTorrentContentLayout(contentLayout);
362 
363  m_currentRule.setIgnoreDays(m_ui->spinIgnorePeriod->value());
364 }
void setTorrentContentLayout(std::optional< BitTorrent::TorrentContentLayout > contentLayout)
void setEpisodeFilter(const QString &e)
void setUseRegex(bool enabled)
void setMustContain(const QString &tokens)
void setSavePath(const QString &savePath)
void setCategory(const QString &category)
void setUseSmartFilter(bool enabled)
void setMustNotContain(const QString &tokens)
void setAddPaused(std::optional< bool > addPaused)

References m_currentRule, m_currentRuleItem, m_ui, RSS::AutoDownloadRule::setAddPaused(), RSS::AutoDownloadRule::setCategory(), RSS::AutoDownloadRule::setEnabled(), RSS::AutoDownloadRule::setEpisodeFilter(), RSS::AutoDownloadRule::setIgnoreDays(), RSS::AutoDownloadRule::setMustContain(), RSS::AutoDownloadRule::setMustNotContain(), RSS::AutoDownloadRule::setSavePath(), RSS::AutoDownloadRule::setTorrentContentLayout(), RSS::AutoDownloadRule::setUseRegex(), and RSS::AutoDownloadRule::setUseSmartFilter().

Referenced by handleRuleDefinitionChanged(), and saveEditedRule().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateEpisodeFilterValidity

void AutomatedRssDownloader::updateEpisodeFilterValidity ( )
privateslot

Definition at line 805 of file automatedrssdownloader.cpp.

806 {
807  const QString text = m_ui->lineEFilter->text();
808  bool valid = text.isEmpty() || m_episodeRegex->match(text).hasMatch();
809 
810  if (valid)
811  {
812  m_ui->lineEFilter->setStyleSheet("");
813  m_ui->labelEpFilterStat->setPixmap(QPixmap());
814  }
815  else
816  {
817  m_ui->lineEFilter->setStyleSheet("QLineEdit { color: #ff0000; }");
818  m_ui->labelEpFilterStat->setPixmap(UIThemeManager::instance()->getIcon("task-attention").pixmap(16, 16));
819  }
820 }

References UIThemeManager::instance(), m_episodeRegex, and m_ui.

Referenced by AutomatedRssDownloader(), clearRuleDefinitionBox(), and updateRuleDefinitionBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateFeedList()

void AutomatedRssDownloader::updateFeedList ( )
private

Definition at line 197 of file automatedrssdownloader.cpp.

198 {
199  const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
200 
201  QList<QListWidgetItem *> selection;
202 
203  if (m_currentRuleItem)
204  selection << m_currentRuleItem;
205  else
206  selection = m_ui->listRules->selectedItems();
207 
208  bool enable = !selection.isEmpty();
209 
210  for (int i = 0; i < m_ui->listFeeds->count(); ++i)
211  {
212  QListWidgetItem *item = m_ui->listFeeds->item(i);
213  const QString feedURL = item->data(Qt::UserRole).toString();
214  item->setHidden(!enable);
215 
216  bool allEnabled = true;
217  bool anyEnabled = false;
218 
219  for (const QListWidgetItem *ruleItem : asConst(selection))
220  {
221  const auto rule = RSS::AutoDownloader::instance()->ruleByName(ruleItem->text());
222  if (rule.feedURLs().contains(feedURL))
223  anyEnabled = true;
224  else
225  allEnabled = false;
226  }
227 
228  if (anyEnabled && allEnabled)
229  item->setCheckState(Qt::Checked);
230  else if (anyEnabled)
231  item->setCheckState(Qt::PartiallyChecked);
232  else
233  item->setCheckState(Qt::Unchecked);
234  }
235 
236  m_ui->listFeeds->sortItems();
237  m_ui->lblListFeeds->setEnabled(enable);
238  m_ui->listFeeds->setEnabled(enable);
239 }

References asConst(), RSS::AutoDownloader::instance(), m_currentRuleItem, m_ui, and RSS::AutoDownloader::ruleByName().

Referenced by loadFeedList(), and updateRuleDefinitionBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateFieldsToolTips

void AutomatedRssDownloader::updateFieldsToolTips ( bool  regex)
privateslot

Definition at line 682 of file automatedrssdownloader.cpp.

683 {
684  QString tip;
685  if (regex)
686  {
687  tip = "<p>" + tr("Regex mode: use Perl-compatible regular expressions") + "</p>";
688  }
689  else
690  {
691  tip = "<p>" + tr("Wildcard mode: you can use") + "<ul>"
692  + "<li>" + tr("? to match any single character") + "</li>"
693  + "<li>" + tr("* to match zero or more of any characters") + "</li>"
694  + "<li>" + tr("Whitespaces count as AND operators (all words, any order)") + "</li>"
695  + "<li>" + tr("| is used as OR operator") + "</li></ul></p>"
696  + "<p>" + tr("If word order is important use * instead of whitespace.") + "</p>";
697  }
698 
699  // Whether regex or wildcard, warn about a potential gotcha for users.
700  // Explanatory string broken over multiple lines for readability (and multiple
701  // statements to prevent uncrustify indenting excessively.
702  tip += "<p>";
703  tip += tr("An expression with an empty %1 clause (e.g. %2)",
704  "We talk about regex/wildcards in the RSS filters section here."
705  " So a valid sentence would be: An expression with an empty | clause (e.g. expr|)"
706  ).arg("<tt>|</tt>", "<tt>expr|</tt>");
707  m_ui->lineContains->setToolTip(tip + tr(" will match all articles.") + "</p>");
708  m_ui->lineNotContains->setToolTip(tip + tr(" will exclude all articles.") + "</p>");
709 }

References m_ui.

Referenced by AutomatedRssDownloader(), clearRuleDefinitionBox(), and updateRuleDefinitionBox().

Here is the caller graph for this function:

◆ updateMatchingArticles()

void AutomatedRssDownloader::updateMatchingArticles ( )
private

Definition at line 607 of file automatedrssdownloader.cpp.

608 {
609  m_ui->treeMatchingArticles->clear();
610 
611  for (const QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems()))
612  {
613  RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
614  ? m_currentRule
615  : RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
616  for (const QString &feedURL : asConst(rule.feedURLs()))
617  {
618  auto feed = RSS::Session::instance()->feedByURL(feedURL);
619  if (!feed) continue; // feed doesn't exist
620 
621  QStringList matchingArticles;
622  for (const auto article : asConst(feed->articles()))
623  if (rule.matches(article->data()))
624  matchingArticles << article->title();
625  if (!matchingArticles.isEmpty())
626  addFeedArticlesToTree(feed, matchingArticles);
627  }
628  }
629 
630  m_treeListEntries.clear();
631 }
void addFeedArticlesToTree(RSS::Feed *feed, const QStringList &articles)
bool matches(const QVariantHash &articleData) const
QString title() const
Definition: rss_feed.cpp:159
Feed * feedByURL(const QString &url) const

References addFeedArticlesToTree(), asConst(), RSS::Session::feedByURL(), RSS::AutoDownloadRule::feedURLs(), RSS::AutoDownloader::instance(), RSS::Session::instance(), m_currentRule, m_currentRuleItem, m_treeListEntries, m_ui, RSS::AutoDownloadRule::matches(), RSS::AutoDownloader::ruleByName(), and RSS::Feed::title().

Referenced by handleRuleDefinitionChanged(), and updateRuleDefinitionBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateMustLineValidity

void AutomatedRssDownloader::updateMustLineValidity ( )
privateslot

Definition at line 711 of file automatedrssdownloader.cpp.

712 {
713  const QString text = m_ui->lineContains->text();
714  bool isRegex = m_ui->checkRegex->isChecked();
715  bool valid = true;
716  QString error;
717 
718  if (!text.isEmpty())
719  {
720  QStringList tokens;
721  if (isRegex)
722  {
723  tokens << text;
724  }
725  else
726  {
727  for (const QString &token : asConst(text.split('|')))
728  tokens << Utils::String::wildcardToRegexPattern(token);
729  }
730 
731  for (const QString &token : asConst(tokens))
732  {
733  QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
734  if (!reg.isValid())
735  {
736  if (isRegex)
737  error = tr("Position %1: %2").arg(reg.patternErrorOffset()).arg(reg.errorString());
738  valid = false;
739  break;
740  }
741  }
742  }
743 
744  if (valid)
745  {
746  m_ui->lineContains->setStyleSheet("");
747  m_ui->labelMustStat->setPixmap(QPixmap());
748  m_ui->labelMustStat->setToolTip("");
749  }
750  else
751  {
752  m_ui->lineContains->setStyleSheet("QLineEdit { color: #ff0000; }");
753  m_ui->labelMustStat->setPixmap(UIThemeManager::instance()->getIcon("task-attention").pixmap(16, 16));
754  m_ui->labelMustStat->setToolTip(error);
755  }
756 }
QString wildcardToRegexPattern(const QString &pattern)
Definition: string.cpp:57

References asConst(), UIThemeManager::instance(), m_ui, and Utils::String::wildcardToRegexPattern().

Referenced by AutomatedRssDownloader(), clearRuleDefinitionBox(), and updateRuleDefinitionBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateMustNotLineValidity

void AutomatedRssDownloader::updateMustNotLineValidity ( )
privateslot

Definition at line 758 of file automatedrssdownloader.cpp.

759 {
760  const QString text = m_ui->lineNotContains->text();
761  bool isRegex = m_ui->checkRegex->isChecked();
762  bool valid = true;
763  QString error;
764 
765  if (!text.isEmpty())
766  {
767  QStringList tokens;
768  if (isRegex)
769  {
770  tokens << text;
771  }
772  else
773  {
774  for (const QString &token : asConst(text.split('|')))
775  tokens << Utils::String::wildcardToRegexPattern(token);
776  }
777 
778  for (const QString &token : asConst(tokens))
779  {
780  QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
781  if (!reg.isValid())
782  {
783  if (isRegex)
784  error = tr("Position %1: %2").arg(reg.patternErrorOffset()).arg(reg.errorString());
785  valid = false;
786  break;
787  }
788  }
789  }
790 
791  if (valid)
792  {
793  m_ui->lineNotContains->setStyleSheet("");
794  m_ui->labelMustNotStat->setPixmap(QPixmap());
795  m_ui->labelMustNotStat->setToolTip("");
796  }
797  else
798  {
799  m_ui->lineNotContains->setStyleSheet("QLineEdit { color: #ff0000; }");
800  m_ui->labelMustNotStat->setPixmap(UIThemeManager::instance()->getIcon("task-attention").pixmap(16, 16));
801  m_ui->labelMustNotStat->setToolTip(error);
802  }
803 }

References asConst(), UIThemeManager::instance(), m_ui, and Utils::String::wildcardToRegexPattern().

Referenced by AutomatedRssDownloader(), clearRuleDefinitionBox(), and updateRuleDefinitionBox().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ updateRuleDefinitionBox

void AutomatedRssDownloader::updateRuleDefinitionBox ( )
privateslot

Definition at line 241 of file automatedrssdownloader.cpp.

242 {
243  const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
244  QListWidgetItem *currentRuleItem = ((selection.count() == 1) ? selection.first() : nullptr);
245  if (m_currentRuleItem != currentRuleItem)
246  {
247  saveEditedRule(); // Save previous rule first
248  m_currentRuleItem = currentRuleItem;
249  //m_ui->listRules->setCurrentItem(m_currentRuleItem);
250  }
251 
252  // Update rule definition box
253  if (m_currentRuleItem)
254  {
256 
257  m_ui->lineContains->setText(m_currentRule.mustContain());
258  m_ui->lineNotContains->setText(m_currentRule.mustNotContain());
259  if (!m_currentRule.episodeFilter().isEmpty())
260  m_ui->lineEFilter->setText(m_currentRule.episodeFilter());
261  else
262  m_ui->lineEFilter->clear();
263  m_ui->checkBoxSaveDiffDir->setChecked(!m_currentRule.savePath().isEmpty());
264  m_ui->lineSavePath->setSelectedPath(Utils::Fs::toNativePath(m_currentRule.savePath()));
265  m_ui->checkRegex->blockSignals(true);
266  m_ui->checkRegex->setChecked(m_currentRule.useRegex());
267  m_ui->checkRegex->blockSignals(false);
268  m_ui->checkSmart->blockSignals(true);
269  m_ui->checkSmart->setChecked(m_currentRule.useSmartFilter());
270  m_ui->checkSmart->blockSignals(false);
271  m_ui->comboCategory->setCurrentIndex(m_ui->comboCategory->findText(m_currentRule.assignedCategory()));
272  if (m_currentRule.assignedCategory().isEmpty())
273  m_ui->comboCategory->clearEditText();
274  int index = 0;
275  if (m_currentRule.addPaused().has_value())
276  index = (*m_currentRule.addPaused() ? 1 : 2);
277  m_ui->comboAddPaused->setCurrentIndex(index);
278  index = 0;
280  index = static_cast<int>(*m_currentRule.torrentContentLayout()) + 1;
281  m_ui->comboContentLayout->setCurrentIndex(index);
282  m_ui->spinIgnorePeriod->setValue(m_currentRule.ignoreDays());
283  QDateTime dateTime = m_currentRule.lastMatch();
284  QString lMatch;
285  if (dateTime.isValid())
286  lMatch = tr("Last Match: %1 days ago").arg(dateTime.daysTo(QDateTime::currentDateTime()));
287  else
288  lMatch = tr("Last Match: Unknown");
289  m_ui->lblLastMatch->setText(lMatch);
293 
294  updateFieldsToolTips(m_ui->checkRegex->isChecked());
295  m_ui->ruleDefBox->setEnabled(true);
296  }
297  else
298  {
301  m_ui->ruleDefBox->setEnabled(false);
302  }
303 
304  updateFeedList();
306 }
std::optional< BitTorrent::TorrentContentLayout > torrentContentLayout() const
std::optional< bool > addPaused() const
QString toNativePath(const QString &path)
Definition: fs.cpp:64

References RSS::AutoDownloadRule::addPaused(), RSS::AutoDownloadRule::assignedCategory(), clearRuleDefinitionBox(), RSS::AutoDownloadRule::episodeFilter(), RSS::AutoDownloadRule::ignoreDays(), RSS::AutoDownloader::instance(), RSS::AutoDownloadRule::lastMatch(), m_currentRule, m_currentRuleItem, m_ui, RSS::AutoDownloadRule::mustContain(), RSS::AutoDownloadRule::mustNotContain(), RSS::AutoDownloader::ruleByName(), saveEditedRule(), RSS::AutoDownloadRule::savePath(), Utils::Fs::toNativePath(), RSS::AutoDownloadRule::torrentContentLayout(), updateEpisodeFilterValidity(), updateFeedList(), updateFieldsToolTips(), updateMatchingArticles(), updateMustLineValidity(), updateMustNotLineValidity(), RSS::AutoDownloadRule::useRegex(), and RSS::AutoDownloadRule::useSmartFilter().

Referenced by AutomatedRssDownloader().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_currentRule

◆ m_currentRuleItem

◆ m_episodeRegex

QRegularExpression* AutomatedRssDownloader::m_episodeRegex
private

◆ m_formatFilterJSON

const QString AutomatedRssDownloader::m_formatFilterJSON
private

Definition at line 100 of file automatedrssdownloader.h.

Referenced by on_exportBtn_clicked(), and on_importBtn_clicked().

◆ m_formatFilterLegacy

const QString AutomatedRssDownloader::m_formatFilterLegacy
private

Definition at line 101 of file automatedrssdownloader.h.

Referenced by on_exportBtn_clicked(), and on_importBtn_clicked().

◆ m_itemsByRuleName

QHash<QString, QListWidgetItem *> AutomatedRssDownloader::m_itemsByRuleName
private

◆ m_treeListEntries

QSet<std::pair<QString, QString> > AutomatedRssDownloader::m_treeListEntries
private

Definition at line 105 of file automatedrssdownloader.h.

Referenced by addFeedArticlesToTree(), and updateMatchingArticles().

◆ m_ui


The documentation for this class was generated from the following files: