Browse Source

Bugfix RSS feed list and rules editor. Closes #3782, #6281.

--HG--
branch : magao-dev
adaptive-webui-19844
Tim Delaney 8 years ago
parent
commit
f96eb587ff
  1. 205
      src/gui/rss/automatedrssdownloader.cpp
  2. 16
      src/gui/rss/automatedrssdownloader.h
  3. 8
      src/gui/rss/automatedrssdownloader.ui
  4. 22
      src/gui/rss/rss_imp.cpp

205
src/gui/rss/automatedrssdownloader.cpp

@ -62,6 +62,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>
ui->listRules->setSortingEnabled(true); ui->listRules->setSortingEnabled(true);
ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection); ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection);
ui->treeMatchingArticles->setSortingEnabled(true); ui->treeMatchingArticles->setSortingEnabled(true);
ui->treeMatchingArticles->sortByColumn(0, Qt::AscendingOrder);
ui->hsplitter->setCollapsible(0, false); ui->hsplitter->setCollapsible(0, false);
ui->hsplitter->setCollapsible(1, false); ui->hsplitter->setCollapsible(1, false);
ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible
@ -85,16 +86,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>
+ "<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>"; + "<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>";
ui->lineEFilter->setToolTip(tip); ui->lineEFilter->setToolTip(tip);
initCategoryCombobox(); initCategoryCombobox();
loadFeedList();
loadSettings(); loadSettings();
ok = connect(ui->listRules, SIGNAL(itemSelectionChanged()), SLOT(updateRuleDefinitionBox()));
Q_ASSERT(ok);
ok = connect(ui->listRules, SIGNAL(itemSelectionChanged()), SLOT(updateFeedList()));
Q_ASSERT(ok);
ok = connect(ui->listRules, SIGNAL(itemChanged(QListWidgetItem *)), SLOT(handleRuleCheckStateChange(QListWidgetItem *)));
Q_ASSERT(ok);
ok = connect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem *)), SLOT(handleFeedCheckStateChange(QListWidgetItem *)));
Q_ASSERT(ok);
// Update matching articles when necessary // Update matching articles when necessary
ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles())); ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles()));
Q_ASSERT(ok); Q_ASSERT(ok);
@ -124,8 +116,8 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>
deleteHotkey = new QShortcut(QKeySequence::Delete, ui->listRules, 0, 0, Qt::WidgetShortcut); deleteHotkey = new QShortcut(QKeySequence::Delete, ui->listRules, 0, 0, Qt::WidgetShortcut);
ok = connect(deleteHotkey, SIGNAL(activated()), SLOT(on_removeRuleBtn_clicked())); ok = connect(deleteHotkey, SIGNAL(activated()), SLOT(on_removeRuleBtn_clicked()));
Q_ASSERT(ok); Q_ASSERT(ok);
updateRuleDefinitionBox(); updateRuleDefinitionBox();
updateFeedList();
} }
AutomatedRssDownloader::~AutomatedRssDownloader() AutomatedRssDownloader::~AutomatedRssDownloader()
@ -138,6 +130,22 @@ AutomatedRssDownloader::~AutomatedRssDownloader()
delete m_episodeRegex; delete m_episodeRegex;
} }
void AutomatedRssDownloader::connectRuleFeedSlots()
{
qDebug() << Q_FUNC_INFO << "Connecting rule and feed slots";
connect(ui->listRules, SIGNAL(itemSelectionChanged()), this, SLOT(updateRuleDefinitionBox()), Qt::UniqueConnection);
connect(ui->listRules, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(handleRuleCheckStateChange(QListWidgetItem *)), Qt::UniqueConnection);
connect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(handleFeedCheckStateChange(QListWidgetItem *)), Qt::UniqueConnection);
}
void AutomatedRssDownloader::disconnectRuleFeedSlots()
{
qDebug() << Q_FUNC_INFO << "Disconnecting rule and feed slots";
disconnect(ui->listRules, SIGNAL(itemSelectionChanged()), this, SLOT(updateRuleDefinitionBox()));
disconnect(ui->listRules, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(handleRuleCheckStateChange(QListWidgetItem *)));
disconnect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(handleFeedCheckStateChange(QListWidgetItem *)));
}
void AutomatedRssDownloader::loadSettings() void AutomatedRssDownloader::loadSettings()
{ {
// load dialog geometry // load dialog geometry
@ -161,9 +169,9 @@ void AutomatedRssDownloader::saveSettings()
void AutomatedRssDownloader::loadRulesList() void AutomatedRssDownloader::loadRulesList()
{ {
// Make sure we save the current item before clearing // Make sure we save the current item before clearing
if (m_editedRule)
saveEditedRule(); saveEditedRule();
ui->listRules->clear(); ui->listRules->clear();
foreach (const QString &rule_name, m_editableRuleList->ruleNames()) { foreach (const QString &rule_name, m_editableRuleList->ruleNames()) {
QListWidgetItem *item = new QListWidgetItem(rule_name, ui->listRules); QListWidgetItem *item = new QListWidgetItem(rule_name, ui->listRules);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
@ -172,36 +180,53 @@ void AutomatedRssDownloader::loadRulesList()
else else
item->setCheckState(Qt::Unchecked); item->setCheckState(Qt::Unchecked);
} }
if (( ui->listRules->count() > 0) && !ui->listRules->currentItem())
ui->listRules->setCurrentRow(0);
} }
void AutomatedRssDownloader::loadFeedList() void AutomatedRssDownloader::loadFeedList()
{ {
disconnectRuleFeedSlots();
const Preferences *const pref = Preferences::instance(); const Preferences *const pref = Preferences::instance();
const QStringList feed_aliases = pref->getRssFeedsAliases(); const QStringList feed_aliases = pref->getRssFeedsAliases();
const QStringList feed_urls = pref->getRssFeedsUrls(); const QStringList feed_urls = pref->getRssFeedsUrls();
QStringList existing_urls; ui->listFeeds->clear();
for (int i = 0; i < feed_aliases.size(); ++i) { for (int i = 0; i < feed_aliases.size(); ++i) {
QString feed_url = feed_urls.at(i); QString feed_url = feed_urls.at(i);
feed_url = feed_url.split("\\").last(); feed_url = feed_url.split("\\").last();
qDebug() << Q_FUNC_INFO << feed_url; qDebug() << Q_FUNC_INFO << feed_url;
if (existing_urls.contains(feed_url)) continue;
QListWidgetItem *item = new QListWidgetItem(feed_aliases.at(i), ui->listFeeds); QListWidgetItem *item = new QListWidgetItem(feed_aliases.at(i), ui->listFeeds);
item->setData(Qt::UserRole, feed_url); item->setData(Qt::UserRole, feed_url);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
existing_urls << feed_url;
} }
// Reconnects slots
updateFeedList();
} }
void AutomatedRssDownloader::updateFeedList() void AutomatedRssDownloader::updateFeedList(QListWidgetItem *selected)
{ {
disconnect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(handleFeedCheckStateChange(QListWidgetItem *))); disconnectRuleFeedSlots();
QList<QListWidgetItem *> selection;
if (selected)
selection << selected;
else
selection = ui->listRules->selectedItems();
bool enable = !selection.isEmpty();
for (int i = 0; i<ui->listFeeds->count(); ++i) { for (int i = 0; i<ui->listFeeds->count(); ++i) {
QListWidgetItem *item = ui->listFeeds->item(i); QListWidgetItem *item = ui->listFeeds->item(i);
const QString feed_url = item->data(Qt::UserRole).toString(); const QString feed_url = item->data(Qt::UserRole).toString();
bool all_enabled = false; item->setHidden(!enable);
foreach (const QListWidgetItem *ruleItem, ui->listRules->selectedItems()) {
bool allEnabled = true;
bool anyEnabled = false;
foreach (const QListWidgetItem *ruleItem, selection) {
Rss::DownloadRulePtr rule = m_editableRuleList->getRule(ruleItem->text()); Rss::DownloadRulePtr rule = m_editableRuleList->getRule(ruleItem->text());
if (!rule) continue; if (!rule) continue;
qDebug() << "Rule" << rule->name() << "affects" << rule->rssFeeds().size() << "feeds."; qDebug() << "Rule" << rule->name() << "affects" << rule->rssFeeds().size() << "feeds.";
@ -209,21 +234,33 @@ void AutomatedRssDownloader::updateFeedList()
qDebug() << "Feed is " << test; qDebug() << "Feed is " << test;
if (rule->rssFeeds().contains(feed_url)) { if (rule->rssFeeds().contains(feed_url)) {
qDebug() << "Rule " << rule->name() << " affects feed " << feed_url; qDebug() << "Rule " << rule->name() << " affects feed " << feed_url;
all_enabled = true; anyEnabled = true;
} }
else { else {
qDebug() << "Rule " << rule->name() << " does NOT affect feed " << feed_url; qDebug() << "Rule " << rule->name() << " does NOT affect feed " << feed_url;
all_enabled = false; allEnabled = false;
break;
} }
} }
if (all_enabled)
if (anyEnabled && allEnabled)
item->setCheckState(Qt::Checked); item->setCheckState(Qt::Checked);
else if (anyEnabled)
item->setCheckState(Qt::PartiallyChecked);
else else
item->setCheckState(Qt::Unchecked); item->setCheckState(Qt::Unchecked);
} }
ui->listFeeds->setEnabled(!ui->listRules->selectedItems().isEmpty());
connect(ui->listFeeds, SIGNAL(itemChanged(QListWidgetItem *)), SLOT(handleFeedCheckStateChange(QListWidgetItem *))); ui->listFeeds->sortItems();
ui->lblListFeeds->setEnabled(enable);
ui->listFeeds->setEnabled(enable);
if (selected) {
m_editedRule = selected;
ui->listRules->clearSelection();
ui->listRules->setCurrentItem(selected);
}
connectRuleFeedSlots();
updateMatchingArticles(); updateMatchingArticles();
} }
@ -232,16 +269,27 @@ bool AutomatedRssDownloader::isRssDownloaderEnabled() const
return ui->checkEnableDownloader->isChecked(); return ui->checkEnableDownloader->isChecked();
} }
void AutomatedRssDownloader::updateRuleDefinitionBox() void AutomatedRssDownloader::updateRuleDefinitionBox(QListWidgetItem *selected)
{ {
disconnectRuleFeedSlots();
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
// Save previous rule first // Save previous rule first
saveEditedRule(); saveEditedRule();
// Update rule definition box // Update rule definition box
const QList<QListWidgetItem *> selection = ui->listRules->selectedItems(); const QList<QListWidgetItem *> selection = ui->listRules->selectedItems();
if (selection.count() == 1) {
m_editedRule = selection.first(); if (!selected && (selection.count() == 1))
Rss::DownloadRulePtr rule = getCurrentRule(); selected = selection.first();
if (selected) {
m_editedRule = selected;
// Cannot call getCurrentRule() here as the current item hasn't been updated yet
// and we could get the details from the wrong rule.
// Also can't set the current item here or the selected items gets messed up.
Rss::DownloadRulePtr rule = m_editableRuleList->getRule(m_editedRule->text());
if (rule) { if (rule) {
ui->lineContains->setText(rule->mustContain()); ui->lineContains->setText(rule->mustContain());
ui->lineNotContains->setText(rule->mustNotContain()); ui->lineNotContains->setText(rule->mustNotContain());
@ -269,37 +317,46 @@ void AutomatedRssDownloader::updateRuleDefinitionBox()
ui->lblLastMatch->setText(lMatch); ui->lblLastMatch->setText(lMatch);
updateMustLineValidity(); updateMustLineValidity();
updateMustNotLineValidity(); updateMustNotLineValidity();
updateEpisodeFilterValidity();
} }
else { else {
// New rule // New rule
clearRuleDefinitionBox(); clearRuleDefinitionBox();
ui->lineContains->setText(selection.first()->text());
ui->comboAddPaused->setCurrentIndex(0); ui->comboAddPaused->setCurrentIndex(0);
ui->comboCategory->setCurrentIndex(0);
ui->spinIgnorePeriod->setValue(0);
} }
updateFieldsToolTips(ui->checkRegex->isChecked()); updateFieldsToolTips(ui->checkRegex->isChecked());
// Enable
ui->ruleDefBox->setEnabled(true); ui->ruleDefBox->setEnabled(true);
} }
else { else {
m_editedRule = 0; m_editedRule = 0;
// Clear
clearRuleDefinitionBox(); clearRuleDefinitionBox();
ui->ruleDefBox->setEnabled(false); ui->ruleDefBox->setEnabled(false);
} }
// Reconnects slots
updateFeedList(selected);
} }
void AutomatedRssDownloader::clearRuleDefinitionBox() void AutomatedRssDownloader::clearRuleDefinitionBox()
{ {
ui->lineContains->clear(); ui->lineContains->clear();
ui->lineNotContains->clear(); ui->lineNotContains->clear();
ui->lineEFilter->clear();
ui->saveDiffDir_check->setChecked(false); ui->saveDiffDir_check->setChecked(false);
ui->lineSavePath->clear(); ui->lineSavePath->clear();
ui->comboCategory->clearEditText(); ui->comboCategory->clearEditText();
ui->comboCategory->setCurrentIndex(-1);
ui->checkRegex->setChecked(false); ui->checkRegex->setChecked(false);
ui->spinIgnorePeriod->setValue(0); ui->spinIgnorePeriod->setValue(0);
ui->comboAddPaused->clearEditText();
ui->comboAddPaused->setCurrentIndex(-1);
updateFieldsToolTips(ui->checkRegex->isChecked()); updateFieldsToolTips(ui->checkRegex->isChecked());
updateMustLineValidity(); updateMustLineValidity();
updateMustNotLineValidity(); updateMustNotLineValidity();
updateEpisodeFilterValidity();
} }
Rss::DownloadRulePtr AutomatedRssDownloader::getCurrentRule() const Rss::DownloadRulePtr AutomatedRssDownloader::getCurrentRule() const
@ -321,7 +378,8 @@ void AutomatedRssDownloader::initCategoryCombobox()
void AutomatedRssDownloader::saveEditedRule() void AutomatedRssDownloader::saveEditedRule()
{ {
if (!m_editedRule) return; if (!m_editedRule || !ui->ruleDefBox->isEnabled()) return;
qDebug() << Q_FUNC_INFO << m_editedRule; qDebug() << Q_FUNC_INFO << m_editedRule;
if (ui->listRules->findItems(m_editedRule->text(), Qt::MatchExactly).isEmpty()) { if (ui->listRules->findItems(m_editedRule->text(), Qt::MatchExactly).isEmpty()) {
qDebug() << "Could not find rule" << m_editedRule->text() << "in the UI list"; qDebug() << "Could not find rule" << m_editedRule->text() << "in the UI list";
@ -356,6 +414,8 @@ void AutomatedRssDownloader::saveEditedRule()
void AutomatedRssDownloader::on_addRuleBtn_clicked() void AutomatedRssDownloader::on_addRuleBtn_clicked()
{ {
saveEditedRule();
// Ask for a rule name // Ask for a rule name
const QString rule_name = AutoExpandableDialog::getText(this, tr("New rule name"), tr("Please type the name of the new download rule.")); const QString rule_name = AutoExpandableDialog::getText(this, tr("New rule name"), tr("Please type the name of the new download rule."));
if (rule_name.isEmpty()) return; if (rule_name.isEmpty()) return;
@ -364,12 +424,17 @@ void AutomatedRssDownloader::on_addRuleBtn_clicked()
QMessageBox::warning(this, tr("Rule name conflict"), tr("A rule with this name already exists, please choose another name.")); QMessageBox::warning(this, tr("Rule name conflict"), tr("A rule with this name already exists, please choose another name."));
return; return;
} }
disconnectRuleFeedSlots();
// Add the new rule to the list // Add the new rule to the list
QListWidgetItem *item = new QListWidgetItem(rule_name, ui->listRules); QListWidgetItem *item = new QListWidgetItem(rule_name, ui->listRules);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
item->setCheckState(Qt::Checked); // Enable as a default item->setCheckState(Qt::Checked); // Enable as a default
ui->listRules->clearSelection(); m_editedRule = 0;
ui->listRules->setCurrentItem(item);
// Reconnects slots
updateRuleDefinitionBox(item);
} }
void AutomatedRssDownloader::on_removeRuleBtn_clicked() void AutomatedRssDownloader::on_removeRuleBtn_clicked()
@ -384,6 +449,9 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked()
confirm_text = tr("Are you sure you want to remove the selected download rules?"); confirm_text = tr("Are you sure you want to remove the selected download rules?");
if (QMessageBox::question(this, tr("Rule deletion confirmation"), confirm_text, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes) if (QMessageBox::question(this, tr("Rule deletion confirmation"), confirm_text, QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
return; return;
disconnectRuleFeedSlots();
foreach (QListWidgetItem *item, selection) { foreach (QListWidgetItem *item, selection) {
// Actually remove the item // Actually remove the item
ui->listRules->removeItemWidget(item); ui->listRules->removeItemWidget(item);
@ -394,6 +462,10 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked()
// Remove it from the m_editableRuleList // Remove it from the m_editableRuleList
m_editableRuleList->removeRule(rule_name); m_editableRuleList->removeRule(rule_name);
} }
m_editedRule = 0;
// Reconnects slots
updateRuleDefinitionBox();
} }
void AutomatedRssDownloader::on_browseSP_clicked() void AutomatedRssDownloader::on_browseSP_clicked()
@ -493,19 +565,17 @@ void AutomatedRssDownloader::renameSelectedRule()
void AutomatedRssDownloader::handleRuleCheckStateChange(QListWidgetItem *rule_item) void AutomatedRssDownloader::handleRuleCheckStateChange(QListWidgetItem *rule_item)
{ {
if (ui->ruleDefBox->isEnabled())
// Make sure the current rule is saved // Make sure the current rule is saved
saveEditedRule(); saveEditedRule();
// Make sure we save the rule that was enabled or disabled - it might not be the current selection. // Make sure we save the rule that was enabled or disabled - it might not be the current selection.
m_editedRule = rule_item; m_editedRule = rule_item;
saveEditedRule(); saveEditedRule();
m_editedRule = 0; updateRuleDefinitionBox();
} }
void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_item) void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_item)
{ {
if (ui->ruleDefBox->isEnabled())
// Make sure the current rule is saved // Make sure the current rule is saved
saveEditedRule(); saveEditedRule();
const QString feed_url = feed_item->data(Qt::UserRole).toString(); const QString feed_url = feed_item->data(Qt::UserRole).toString();
@ -513,11 +583,9 @@ void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_it
Rss::DownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text()); Rss::DownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text());
Q_ASSERT(rule); Q_ASSERT(rule);
QStringList affected_feeds = rule->rssFeeds(); QStringList affected_feeds = rule->rssFeeds();
if (feed_item->checkState() == Qt::Checked) { if ((feed_item->checkState() == Qt::Checked) && !affected_feeds.contains(feed_url))
if (!affected_feeds.contains(feed_url))
affected_feeds << feed_url; affected_feeds << feed_url;
} else if ((feed_item->checkState() == Qt::Unchecked) && affected_feeds.contains(feed_url))
else if (affected_feeds.contains(feed_url))
affected_feeds.removeOne(feed_url); affected_feeds.removeOne(feed_url);
// Save the updated rule // Save the updated rule
if (affected_feeds.size() != rule->rssFeeds().size()) { if (affected_feeds.size() != rule->rssFeeds().size()) {
@ -552,10 +620,15 @@ void AutomatedRssDownloader::updateMatchingArticles()
addFeedArticlesToTree(feed, matching_articles); addFeedArticlesToTree(feed, matching_articles);
} }
} }
m_treeListEntries.clear();
} }
void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, const QStringList &articles) void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, const QStringList &articles)
{ {
// Turn off sorting while inserting
ui->treeMatchingArticles->setSortingEnabled(false);
// Check if this feed is already in the tree // Check if this feed is already in the tree
QTreeWidgetItem *treeFeedItem = 0; QTreeWidgetItem *treeFeedItem = 0;
for (int i = 0; i<ui->treeMatchingArticles->topLevelItemCount(); ++i) { for (int i = 0; i<ui->treeMatchingArticles->topLevelItemCount(); ++i) {
@ -565,6 +638,7 @@ void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, con
break; break;
} }
} }
// If there is none, create it // If there is none, create it
if (!treeFeedItem) { if (!treeFeedItem) {
treeFeedItem = new QTreeWidgetItem(QStringList() << feed->displayName()); treeFeedItem = new QTreeWidgetItem(QStringList() << feed->displayName());
@ -576,13 +650,22 @@ void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, con
treeFeedItem->setData(0, Qt::UserRole, feed->url()); treeFeedItem->setData(0, Qt::UserRole, feed->url());
ui->treeMatchingArticles->addTopLevelItem(treeFeedItem); ui->treeMatchingArticles->addTopLevelItem(treeFeedItem);
} }
// Insert the articles // Insert the articles
foreach (const QString &art, articles) { foreach (const QString &art, articles) {
QPair<QString, QString> key(feed->displayName(), art);
if (!m_treeListEntries.contains(key)) {
m_treeListEntries << key;
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << art); QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << art);
item->setToolTip(0, art); item->setToolTip(0, art);
treeFeedItem->addChild(item); treeFeedItem->addChild(item);
} }
}
ui->treeMatchingArticles->expandItem(treeFeedItem); ui->treeMatchingArticles->expandItem(treeFeedItem);
ui->treeMatchingArticles->sortItems(0, Qt::AscendingOrder);
ui->treeMatchingArticles->setSortingEnabled(true);
} }
void AutomatedRssDownloader::updateFieldsToolTips(bool regex) void AutomatedRssDownloader::updateFieldsToolTips(bool regex)
@ -609,11 +692,13 @@ void AutomatedRssDownloader::updateMustLineValidity()
{ {
const QString text = ui->lineContains->text(); const QString text = ui->lineContains->text();
bool valid = true; bool valid = true;
if (!text.isEmpty()) {
QStringList tokens; QStringList tokens;
if (ui->checkRegex->isChecked()) if (ui->checkRegex->isChecked())
tokens << text; tokens << text;
else else
tokens << text.split(" "); tokens << text.split("|");
foreach (const QString &token, tokens) { foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard); QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
if (!reg.isValid()) { if (!reg.isValid()) {
@ -621,6 +706,8 @@ void AutomatedRssDownloader::updateMustLineValidity()
break; break;
} }
} }
}
if (valid) { if (valid) {
ui->lineContains->setStyleSheet(""); ui->lineContains->setStyleSheet("");
ui->lbl_must_stat->setPixmap(QPixmap()); ui->lbl_must_stat->setPixmap(QPixmap());
@ -635,6 +722,8 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
{ {
const QString text = ui->lineNotContains->text(); const QString text = ui->lineNotContains->text();
bool valid = true; bool valid = true;
if (!text.isEmpty()) {
QStringList tokens; QStringList tokens;
if (ui->checkRegex->isChecked()) if (ui->checkRegex->isChecked())
tokens << text; tokens << text;
@ -647,6 +736,8 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
break; break;
} }
} }
}
if (valid) { if (valid) {
ui->lineNotContains->setStyleSheet(""); ui->lineNotContains->setStyleSheet("");
ui->lbl_mustnot_stat->setPixmap(QPixmap()); ui->lbl_mustnot_stat->setPixmap(QPixmap());
@ -660,7 +751,8 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
void AutomatedRssDownloader::updateEpisodeFilterValidity() void AutomatedRssDownloader::updateEpisodeFilterValidity()
{ {
const QString text = ui->lineEFilter->text(); const QString text = ui->lineEFilter->text();
bool valid = m_episodeRegex->indexIn(text) != -1; bool valid = text.isEmpty() || m_episodeRegex->indexIn(text) != -1;
if (valid) { if (valid) {
ui->lineEFilter->setStyleSheet(""); ui->lineEFilter->setStyleSheet("");
ui->lbl_epfilter_stat->setPixmap(QPixmap()); ui->lbl_epfilter_stat->setPixmap(QPixmap());
@ -671,12 +763,31 @@ void AutomatedRssDownloader::updateEpisodeFilterValidity()
} }
} }
void AutomatedRssDownloader::showEvent(QShowEvent *event)
{
// Connects the signals and slots
loadFeedList();
QDialog::showEvent(event);
}
void AutomatedRssDownloader::hideEvent(QHideEvent *event)
{
disconnectRuleFeedSlots();
QDialog::hideEvent(event);
}
void AutomatedRssDownloader::onFinished(int result) void AutomatedRssDownloader::onFinished(int result)
{ {
Q_UNUSED(result); Q_UNUSED(result);
disconnectRuleFeedSlots();
// Save current item on exit // Save current item on exit
saveEditedRule(); saveEditedRule();
ui->listRules->clearSelection();
m_ruleList->replace(m_editableRuleList); m_ruleList->replace(m_editableRuleList);
m_ruleList->saveRulesToStorage(); m_ruleList->saveRulesToStorage();
saveSettings(); saveSettings();
m_treeListEntries.clear();
ui->treeMatchingArticles->clear();
} }

16
src/gui/rss/automatedrssdownloader.h

@ -32,8 +32,13 @@
#define AUTOMATEDRSSDOWNLOADER_H #define AUTOMATEDRSSDOWNLOADER_H
#include <QDialog> #include <QDialog>
#include <QHideEvent>
#include <QPair>
#include <QRegExpValidator> #include <QRegExpValidator>
#include <QSet>
#include <QShortcut> #include <QShortcut>
#include <QShowEvent>
#include <QString>
#include <QWeakPointer> #include <QWeakPointer>
#include "base/rss/rssdownloadrule.h" #include "base/rss/rssdownloadrule.h"
@ -64,17 +69,21 @@ public:
~AutomatedRssDownloader(); ~AutomatedRssDownloader();
bool isRssDownloaderEnabled() const; bool isRssDownloaderEnabled() const;
protected:
virtual void showEvent(QShowEvent *event) override;
virtual void hideEvent(QHideEvent *event) override;
protected slots: protected slots:
void loadSettings(); void loadSettings();
void saveSettings(); void saveSettings();
void loadRulesList(); void loadRulesList();
void handleRuleCheckStateChange(QListWidgetItem *rule_item); void handleRuleCheckStateChange(QListWidgetItem *rule_item);
void handleFeedCheckStateChange(QListWidgetItem *feed_item); void handleFeedCheckStateChange(QListWidgetItem *feed_item);
void updateRuleDefinitionBox(); void updateRuleDefinitionBox(QListWidgetItem *selected = 0);
void clearRuleDefinitionBox(); void clearRuleDefinitionBox();
void saveEditedRule(); void saveEditedRule();
void loadFeedList(); void loadFeedList();
void updateFeedList(); void updateFeedList(QListWidgetItem *selected = 0);
private slots: private slots:
void displayRulesListMenu(const QPoint &pos); void displayRulesListMenu(const QPoint &pos);
@ -95,6 +104,8 @@ private:
Rss::DownloadRulePtr getCurrentRule() const; Rss::DownloadRulePtr getCurrentRule() const;
void initCategoryCombobox(); void initCategoryCombobox();
void addFeedArticlesToTree(const Rss::FeedPtr &feed, const QStringList &articles); void addFeedArticlesToTree(const Rss::FeedPtr &feed, const QStringList &articles);
void disconnectRuleFeedSlots();
void connectRuleFeedSlots();
private: private:
Ui::AutomatedRssDownloader *ui; Ui::AutomatedRssDownloader *ui;
@ -105,6 +116,7 @@ private:
QRegExp *m_episodeRegex; QRegExp *m_episodeRegex;
QShortcut *editHotkey; QShortcut *editHotkey;
QShortcut *deleteHotkey; QShortcut *deleteHotkey;
QSet<QPair<QString, QString >> m_treeListEntries;
}; };
#endif // AUTOMATEDRSSDOWNLOADER_H #endif // AUTOMATEDRSSDOWNLOADER_H

8
src/gui/rss/automatedrssdownloader.ui

@ -249,12 +249,18 @@
</item> </item>
<item> <item>
<widget class="QSpinBox" name="spinIgnorePeriod"> <widget class="QSpinBox" name="spinIgnorePeriod">
<property name="specialValueText">
<string>Disabled</string>
</property>
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="suffix"> <property name="suffix">
<string> days</string> <string> days</string>
</property> </property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum"> <property name="maximum">
<number>365</number> <number>365</number>
</property> </property>
@ -314,7 +320,7 @@
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="lblListFeeds">
<property name="font"> <property name="font">
<font> <font>
<weight>50</weight> <weight>50</weight>

22
src/gui/rss/rss_imp.cpp

@ -164,6 +164,7 @@ void RSSImp::askNewFolder()
// Expand parent folder to display new folder // Expand parent folder to display new folder
if (parent_item) if (parent_item)
parent_item->setExpanded(true); parent_item->setExpanded(true);
m_feedList->setCurrentItem(folderItem);
m_rssManager->saveStreamList(); m_rssManager->saveStreamList();
} }
@ -219,7 +220,10 @@ void RSSImp::on_newFeedButton_clicked()
m_feedList->addTopLevelItem(item); m_feedList->addTopLevelItem(item);
// Notify TreeWidget // Notify TreeWidget
m_feedList->itemAdded(item, stream); m_feedList->itemAdded(item, stream);
// Expand parent folder to display new feed
if (parent_item)
parent_item->setExpanded(true);
m_feedList->setCurrentItem(item);
m_rssManager->saveStreamList(); m_rssManager->saveStreamList();
} }
@ -238,6 +242,8 @@ void RSSImp::deleteSelectedItems()
if (answer == QMessageBox::No) if (answer == QMessageBox::No)
return; return;
QList<QString> deleted;
foreach (QTreeWidgetItem *item, selectedItems) { foreach (QTreeWidgetItem *item, selectedItems) {
if (item == m_feedList->stickyUnreadItem()) if (item == m_feedList->stickyUnreadItem())
continue; continue;
@ -247,6 +253,7 @@ void RSSImp::deleteSelectedItems()
m_feedList->itemAboutToBeRemoved(item); m_feedList->itemAboutToBeRemoved(item);
// Actually delete the item // Actually delete the item
rss_item->parentFolder()->removeChild(rss_item->id()); rss_item->parentFolder()->removeChild(rss_item->id());
deleted << rss_item->id();
delete item; delete item;
// Update parents count // Update parents count
while (parent && (parent != m_feedList->invisibleRootItem())) { while (parent && (parent != m_feedList->invisibleRootItem())) {
@ -255,6 +262,10 @@ void RSSImp::deleteSelectedItems()
} }
} }
m_rssManager->saveStreamList(); m_rssManager->saveStreamList();
foreach (const QString &feed_id, deleted)
m_rssManager->forwardFeedInfosChanged(feed_id, "", 0);
// Update Unread items // Update Unread items
updateItemInfos(m_feedList->stickyUnreadItem()); updateItemInfos(m_feedList->stickyUnreadItem());
if (m_feedList->currentItem() == m_feedList->stickyUnreadItem()) if (m_feedList->currentItem() == m_feedList->stickyUnreadItem())
@ -393,6 +404,7 @@ void RSSImp::renameSelectedRssFile()
} while (!ok); } while (!ok);
// Rename item // Rename item
rss_item->rename(newName); rss_item->rename(newName);
m_rssManager->saveStreamList();
// Update TreeWidget // Update TreeWidget
updateItemInfos(item); updateItemInfos(item);
} }
@ -647,6 +659,8 @@ void RSSImp::updateItemInfos(QTreeWidgetItem *item)
void RSSImp::updateFeedIcon(const QString &url, const QString &iconPath) void RSSImp::updateFeedIcon(const QString &url, const QString &iconPath)
{ {
QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url); QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url);
if (item)
item->setData(0, Qt::DecorationRole, QVariant(QIcon(iconPath))); item->setData(0, Qt::DecorationRole, QVariant(QIcon(iconPath)));
} }
@ -654,6 +668,8 @@ void RSSImp::updateFeedInfos(const QString &url, const QString &display_name, ui
{ {
qDebug() << Q_FUNC_INFO << display_name; qDebug() << Q_FUNC_INFO << display_name;
QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url); QTreeWidgetItem *item = m_feedList->getTreeItemFromUrl(url);
if (item) {
Rss::FeedPtr stream = qSharedPointerCast<Rss::Feed>(m_feedList->getRSSItem(item)); Rss::FeedPtr stream = qSharedPointerCast<Rss::Feed>(m_feedList->getRSSItem(item));
item->setText(0, display_name + QString::fromUtf8(" (") + QString::number(nbUnread) + QString(")")); item->setText(0, display_name + QString::fromUtf8(" (") + QString::number(nbUnread) + QString(")"));
if (!stream->isLoading()) if (!stream->isLoading())
@ -661,6 +677,8 @@ void RSSImp::updateFeedInfos(const QString &url, const QString &display_name, ui
// Update parent // Update parent
if (item->parent()) if (item->parent())
updateItemInfos(item->parent()); updateItemInfos(item->parent());
}
// Update Unread item // Update Unread item
updateItemInfos(m_feedList->stickyUnreadItem()); updateItemInfos(m_feedList->stickyUnreadItem());
} }
@ -713,7 +731,9 @@ RSSImp::RSSImp(QWidget *parent)
connect(deleteHotkey, SIGNAL(activated()), SLOT(deleteSelectedItems())); connect(deleteHotkey, SIGNAL(activated()), SLOT(deleteSelectedItems()));
m_rssManager->loadStreamList(); m_rssManager->loadStreamList();
m_feedList->setSortingEnabled(false);
fillFeedsList(); fillFeedsList();
m_feedList->setSortingEnabled(true);
populateArticleList(m_feedList->currentItem()); populateArticleList(m_feedList->currentItem());
loadFoldersOpenState(); loadFoldersOpenState();

Loading…
Cancel
Save