Browse Source

Merge pull request #6326 from magao/issue3782

RSS rules and feed UI bugfixes. Closes #3782, #6281.
adaptive-webui-19844
sledgehammer999 8 years ago committed by GitHub
parent
commit
f78bf27daf
  1. 278
      src/gui/rss/automatedrssdownloader.cpp
  2. 23
      src/gui/rss/automatedrssdownloader.h
  3. 8
      src/gui/rss/automatedrssdownloader.ui
  4. 38
      src/gui/rss/rss_imp.cpp

278
src/gui/rss/automatedrssdownloader.cpp

@ -28,14 +28,14 @@ @@ -28,14 +28,14 @@
* Contact : chris@qbittorrent.org
*/
#include <QMessageBox>
#include <QFileDialog>
#include <QCursor>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QMenu>
#include <QCursor>
#include "base/preferences.h"
#include "base/bittorrent/session.h"
#include "base/preferences.h"
#include "base/rss/rssdownloadrulelist.h"
#include "base/rss/rssmanager.h"
#include "base/rss/rssfolder.h"
@ -48,9 +48,10 @@ @@ -48,9 +48,10 @@
#include "automatedrssdownloader.h"
AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager> &manager, QWidget *parent)
: QDialog(parent),
ui(new Ui::AutomatedRssDownloader),
m_manager(manager), m_editedRule(0)
: QDialog(parent)
, ui(new Ui::AutomatedRssDownloader)
, m_manager(manager)
, m_editedRule(0)
{
ui->setupUi(this);
// Icons
@ -61,6 +62,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager> @@ -61,6 +62,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>
ui->listRules->setSortingEnabled(true);
ui->listRules->setSelectionMode(QAbstractItemView::ExtendedSelection);
ui->treeMatchingArticles->setSortingEnabled(true);
ui->treeMatchingArticles->sortByColumn(0, Qt::AscendingOrder);
ui->hsplitter->setCollapsible(0, false);
ui->hsplitter->setCollapsible(1, false);
ui->hsplitter->setCollapsible(2, true); // Only the preview list is collapsible
@ -84,16 +86,7 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager> @@ -84,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>";
ui->lineEFilter->setToolTip(tip);
initCategoryCombobox();
loadFeedList();
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
ok = connect(ui->lineContains, SIGNAL(textEdited(QString)), SLOT(updateMatchingArticles()));
Q_ASSERT(ok);
@ -123,8 +116,8 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager> @@ -123,8 +116,8 @@ AutomatedRssDownloader::AutomatedRssDownloader(const QWeakPointer<Rss::Manager>
deleteHotkey = new QShortcut(QKeySequence::Delete, ui->listRules, 0, 0, Qt::WidgetShortcut);
ok = connect(deleteHotkey, SIGNAL(activated()), SLOT(on_removeRuleBtn_clicked()));
Q_ASSERT(ok);
updateRuleDefinitionBox();
updateFeedList();
}
AutomatedRssDownloader::~AutomatedRssDownloader()
@ -137,6 +130,22 @@ AutomatedRssDownloader::~AutomatedRssDownloader() @@ -137,6 +130,22 @@ AutomatedRssDownloader::~AutomatedRssDownloader()
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()
{
// load dialog geometry
@ -160,9 +169,9 @@ void AutomatedRssDownloader::saveSettings() @@ -160,9 +169,9 @@ void AutomatedRssDownloader::saveSettings()
void AutomatedRssDownloader::loadRulesList()
{
// Make sure we save the current item before clearing
if (m_editedRule)
saveEditedRule();
saveEditedRule();
ui->listRules->clear();
foreach (const QString &rule_name, m_editableRuleList->ruleNames()) {
QListWidgetItem *item = new QListWidgetItem(rule_name, ui->listRules);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
@ -171,36 +180,53 @@ void AutomatedRssDownloader::loadRulesList() @@ -171,36 +180,53 @@ void AutomatedRssDownloader::loadRulesList()
else
item->setCheckState(Qt::Unchecked);
}
if (( ui->listRules->count() > 0) && !ui->listRules->currentItem())
ui->listRules->setCurrentRow(0);
}
void AutomatedRssDownloader::loadFeedList()
{
disconnectRuleFeedSlots();
const Preferences *const pref = Preferences::instance();
const QStringList feed_aliases = pref->getRssFeedsAliases();
const QStringList feed_urls = pref->getRssFeedsUrls();
QStringList existing_urls;
for (int i = 0; i<feed_aliases.size(); ++i) {
ui->listFeeds->clear();
for (int i = 0; i < feed_aliases.size(); ++i) {
QString feed_url = feed_urls.at(i);
feed_url = feed_url.split("\\").last();
qDebug() << Q_FUNC_INFO << feed_url;
if (existing_urls.contains(feed_url)) continue;
QListWidgetItem *item = new QListWidgetItem(feed_aliases.at(i), ui->listFeeds);
item->setData(Qt::UserRole, feed_url);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
existing_urls << feed_url;
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
}
// 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) {
QListWidgetItem *item = ui->listFeeds->item(i);
const QString feed_url = item->data(Qt::UserRole).toString();
bool all_enabled = false;
foreach (const QListWidgetItem *ruleItem, ui->listRules->selectedItems()) {
item->setHidden(!enable);
bool allEnabled = true;
bool anyEnabled = false;
foreach (const QListWidgetItem *ruleItem, selection) {
Rss::DownloadRulePtr rule = m_editableRuleList->getRule(ruleItem->text());
if (!rule) continue;
qDebug() << "Rule" << rule->name() << "affects" << rule->rssFeeds().size() << "feeds.";
@ -208,21 +234,33 @@ void AutomatedRssDownloader::updateFeedList() @@ -208,21 +234,33 @@ void AutomatedRssDownloader::updateFeedList()
qDebug() << "Feed is " << test;
if (rule->rssFeeds().contains(feed_url)) {
qDebug() << "Rule " << rule->name() << " affects feed " << feed_url;
all_enabled = true;
anyEnabled = true;
}
else {
qDebug() << "Rule " << rule->name() << " does NOT affect feed " << feed_url;
all_enabled = false;
break;
allEnabled = false;
}
}
if (all_enabled)
if (anyEnabled && allEnabled)
item->setCheckState(Qt::Checked);
else if (anyEnabled)
item->setCheckState(Qt::PartiallyChecked);
else
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();
}
@ -231,16 +269,27 @@ bool AutomatedRssDownloader::isRssDownloaderEnabled() const @@ -231,16 +269,27 @@ bool AutomatedRssDownloader::isRssDownloaderEnabled() const
return ui->checkEnableDownloader->isChecked();
}
void AutomatedRssDownloader::updateRuleDefinitionBox()
void AutomatedRssDownloader::updateRuleDefinitionBox(QListWidgetItem *selected)
{
disconnectRuleFeedSlots();
qDebug() << Q_FUNC_INFO;
// Save previous rule first
saveEditedRule();
// Update rule definition box
const QList<QListWidgetItem *> selection = ui->listRules->selectedItems();
if (selection.count() == 1) {
m_editedRule = selection.first();
Rss::DownloadRulePtr rule = getCurrentRule();
if (!selected && (selection.count() == 1))
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) {
ui->lineContains->setText(rule->mustContain());
ui->lineNotContains->setText(rule->mustNotContain());
@ -268,37 +317,46 @@ void AutomatedRssDownloader::updateRuleDefinitionBox() @@ -268,37 +317,46 @@ void AutomatedRssDownloader::updateRuleDefinitionBox()
ui->lblLastMatch->setText(lMatch);
updateMustLineValidity();
updateMustNotLineValidity();
updateEpisodeFilterValidity();
}
else {
// New rule
clearRuleDefinitionBox();
ui->lineContains->setText(selection.first()->text());
ui->comboAddPaused->setCurrentIndex(0);
ui->comboCategory->setCurrentIndex(0);
ui->spinIgnorePeriod->setValue(0);
}
updateFieldsToolTips(ui->checkRegex->isChecked());
// Enable
ui->ruleDefBox->setEnabled(true);
}
else {
m_editedRule = 0;
// Clear
clearRuleDefinitionBox();
ui->ruleDefBox->setEnabled(false);
}
// Reconnects slots
updateFeedList(selected);
}
void AutomatedRssDownloader::clearRuleDefinitionBox()
{
ui->lineContains->clear();
ui->lineNotContains->clear();
ui->lineEFilter->clear();
ui->saveDiffDir_check->setChecked(false);
ui->lineSavePath->clear();
ui->comboCategory->clearEditText();
ui->comboCategory->setCurrentIndex(-1);
ui->checkRegex->setChecked(false);
ui->spinIgnorePeriod->setValue(0);
ui->comboAddPaused->clearEditText();
ui->comboAddPaused->setCurrentIndex(-1);
updateFieldsToolTips(ui->checkRegex->isChecked());
updateMustLineValidity();
updateMustNotLineValidity();
updateEpisodeFilterValidity();
}
Rss::DownloadRulePtr AutomatedRssDownloader::getCurrentRule() const
@ -320,7 +378,8 @@ void AutomatedRssDownloader::initCategoryCombobox() @@ -320,7 +378,8 @@ void AutomatedRssDownloader::initCategoryCombobox()
void AutomatedRssDownloader::saveEditedRule()
{
if (!m_editedRule) return;
if (!m_editedRule || !ui->ruleDefBox->isEnabled()) return;
qDebug() << Q_FUNC_INFO << m_editedRule;
if (ui->listRules->findItems(m_editedRule->text(), Qt::MatchExactly).isEmpty()) {
qDebug() << "Could not find rule" << m_editedRule->text() << "in the UI list";
@ -355,6 +414,8 @@ void AutomatedRssDownloader::saveEditedRule() @@ -355,6 +414,8 @@ void AutomatedRssDownloader::saveEditedRule()
void AutomatedRssDownloader::on_addRuleBtn_clicked()
{
saveEditedRule();
// 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."));
if (rule_name.isEmpty()) return;
@ -363,12 +424,17 @@ void AutomatedRssDownloader::on_addRuleBtn_clicked() @@ -363,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."));
return;
}
disconnectRuleFeedSlots();
// Add the new rule to the list
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
ui->listRules->clearSelection();
ui->listRules->setCurrentItem(item);
m_editedRule = 0;
// Reconnects slots
updateRuleDefinitionBox(item);
}
void AutomatedRssDownloader::on_removeRuleBtn_clicked()
@ -383,6 +449,9 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked() @@ -383,6 +449,9 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked()
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)
return;
disconnectRuleFeedSlots();
foreach (QListWidgetItem *item, selection) {
// Actually remove the item
ui->listRules->removeItemWidget(item);
@ -393,6 +462,10 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked() @@ -393,6 +462,10 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked()
// Remove it from the m_editableRuleList
m_editableRuleList->removeRule(rule_name);
}
m_editedRule = 0;
// Reconnects slots
updateRuleDefinitionBox();
}
void AutomatedRssDownloader::on_browseSP_clicked()
@ -492,31 +565,27 @@ void AutomatedRssDownloader::renameSelectedRule() @@ -492,31 +565,27 @@ void AutomatedRssDownloader::renameSelectedRule()
void AutomatedRssDownloader::handleRuleCheckStateChange(QListWidgetItem *rule_item)
{
if (ui->ruleDefBox->isEnabled())
// Make sure the current rule is saved
saveEditedRule();
// Make sure the current rule is saved
saveEditedRule();
// Make sure we save the rule that was enabled or disabled - it might not be the current selection.
m_editedRule = rule_item;
saveEditedRule();
m_editedRule = 0;
updateRuleDefinitionBox();
}
void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feed_item)
{
if (ui->ruleDefBox->isEnabled())
// Make sure the current rule is saved
saveEditedRule();
// Make sure the current rule is saved
saveEditedRule();
const QString feed_url = feed_item->data(Qt::UserRole).toString();
foreach (QListWidgetItem *rule_item, ui->listRules->selectedItems()) {
Rss::DownloadRulePtr rule = m_editableRuleList->getRule(rule_item->text());
Q_ASSERT(rule);
QStringList affected_feeds = rule->rssFeeds();
if (feed_item->checkState() == Qt::Checked) {
if (!affected_feeds.contains(feed_url))
affected_feeds << feed_url;
}
else if (affected_feeds.contains(feed_url))
if ((feed_item->checkState() == Qt::Checked) && !affected_feeds.contains(feed_url))
affected_feeds << feed_url;
else if ((feed_item->checkState() == Qt::Unchecked) && affected_feeds.contains(feed_url))
affected_feeds.removeOne(feed_url);
// Save the updated rule
if (affected_feeds.size() != rule->rssFeeds().size()) {
@ -551,10 +620,15 @@ void AutomatedRssDownloader::updateMatchingArticles() @@ -551,10 +620,15 @@ void AutomatedRssDownloader::updateMatchingArticles()
addFeedArticlesToTree(feed, matching_articles);
}
}
m_treeListEntries.clear();
}
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
QTreeWidgetItem *treeFeedItem = 0;
for (int i = 0; i<ui->treeMatchingArticles->topLevelItemCount(); ++i) {
@ -564,6 +638,7 @@ void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, con @@ -564,6 +638,7 @@ void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, con
break;
}
}
// If there is none, create it
if (!treeFeedItem) {
treeFeedItem = new QTreeWidgetItem(QStringList() << feed->displayName());
@ -575,13 +650,22 @@ void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, con @@ -575,13 +650,22 @@ void AutomatedRssDownloader::addFeedArticlesToTree(const Rss::FeedPtr &feed, con
treeFeedItem->setData(0, Qt::UserRole, feed->url());
ui->treeMatchingArticles->addTopLevelItem(treeFeedItem);
}
// Insert the articles
foreach (const QString &art, articles) {
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << art);
item->setToolTip(0, art);
treeFeedItem->addChild(item);
QPair<QString, QString> key(feed->displayName(), art);
if (!m_treeListEntries.contains(key)) {
m_treeListEntries << key;
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << art);
item->setToolTip(0, art);
treeFeedItem->addChild(item);
}
}
ui->treeMatchingArticles->expandItem(treeFeedItem);
ui->treeMatchingArticles->sortItems(0, Qt::AscendingOrder);
ui->treeMatchingArticles->setSortingEnabled(true);
}
void AutomatedRssDownloader::updateFieldsToolTips(bool regex)
@ -608,18 +692,22 @@ void AutomatedRssDownloader::updateMustLineValidity() @@ -608,18 +692,22 @@ void AutomatedRssDownloader::updateMustLineValidity()
{
const QString text = ui->lineContains->text();
bool valid = true;
QStringList tokens;
if (ui->checkRegex->isChecked())
tokens << text;
else
tokens << text.split(" ");
foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
if (!reg.isValid()) {
valid = false;
break;
if (!text.isEmpty()) {
QStringList tokens;
if (ui->checkRegex->isChecked())
tokens << text;
else
tokens << text.split("|");
foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
if (!reg.isValid()) {
valid = false;
break;
}
}
}
if (valid) {
ui->lineContains->setStyleSheet("");
ui->lbl_must_stat->setPixmap(QPixmap());
@ -634,18 +722,22 @@ void AutomatedRssDownloader::updateMustNotLineValidity() @@ -634,18 +722,22 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
{
const QString text = ui->lineNotContains->text();
bool valid = true;
QStringList tokens;
if (ui->checkRegex->isChecked())
tokens << text;
else
tokens << text.split("|");
foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
if (!reg.isValid()) {
valid = false;
break;
if (!text.isEmpty()) {
QStringList tokens;
if (ui->checkRegex->isChecked())
tokens << text;
else
tokens << text.split("|");
foreach (const QString &token, tokens) {
QRegExp reg(token, Qt::CaseInsensitive, ui->checkRegex->isChecked() ? QRegExp::RegExp : QRegExp::Wildcard);
if (!reg.isValid()) {
valid = false;
break;
}
}
}
if (valid) {
ui->lineNotContains->setStyleSheet("");
ui->lbl_mustnot_stat->setPixmap(QPixmap());
@ -659,7 +751,8 @@ void AutomatedRssDownloader::updateMustNotLineValidity() @@ -659,7 +751,8 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
void AutomatedRssDownloader::updateEpisodeFilterValidity()
{
const QString text = ui->lineEFilter->text();
bool valid = m_episodeRegex->indexIn(text) != -1;
bool valid = text.isEmpty() || m_episodeRegex->indexIn(text) != -1;
if (valid) {
ui->lineEFilter->setStyleSheet("");
ui->lbl_epfilter_stat->setPixmap(QPixmap());
@ -670,12 +763,31 @@ void AutomatedRssDownloader::updateEpisodeFilterValidity() @@ -670,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)
{
Q_UNUSED(result);
disconnectRuleFeedSlots();
// Save current item on exit
saveEditedRule();
ui->listRules->clearSelection();
m_ruleList->replace(m_editableRuleList);
m_ruleList->saveRulesToStorage();
saveSettings();
m_treeListEntries.clear();
ui->treeMatchingArticles->clear();
}

23
src/gui/rss/automatedrssdownloader.h

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

8
src/gui/rss/automatedrssdownloader.ui

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

38
src/gui/rss/rss_imp.cpp

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

Loading…
Cancel
Save