|
|
@ -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(); |
|
|
|
} |
|
|
|
} |
|
|
|