Now able to add filters too.

This commit is contained in:
Martin Rotter 2020-07-09 11:51:48 +02:00
parent 09fdf72d26
commit 2e04963acc
9 changed files with 124 additions and 14 deletions

View File

@ -68,7 +68,7 @@ class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel {
QList<Message> messagesForItem(RootItem* item) const;
// Returns ALL RECURSIVE CHILD feeds contained within single index.
QList<Feed*> feedsForIndex(const QModelIndex& index) const;
QList<Feed*> feedsForIndex(const QModelIndex& index = QModelIndex()) const;
// Returns feed/category which lies at the specified index or
// root item if index is invalid.
@ -156,7 +156,6 @@ class RSSGUARD_DLLSPEC FeedsModel : public QAbstractItemModel {
private:
RootItem* m_rootItem;
int m_itemHeight;
QList<QString> m_headerData;
QList<QString> m_tooltipData;
QIcon m_countsIcon;

View File

@ -81,3 +81,7 @@ QString MessageFilter::script() const {
void MessageFilter::setScript(const QString& script) {
m_script = script;
}
void MessageFilter::setId(int id) {
m_id = id;
}

View File

@ -19,6 +19,7 @@ class MessageFilter : public QObject {
FilteringAction filterMessage(QJSEngine* engine);
int id() const;
void setId(int id);
QString name() const;
void setName(const QString& name);

View File

@ -42,6 +42,8 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q
this, &FormMessageFiltersManager::loadFilter);
connect(m_ui.m_btnAddNew, &QPushButton::clicked,
this, &FormMessageFiltersManager::addNewFilter);
connect(m_ui.m_btnRemoveSelected, &QPushButton::clicked,
this, &FormMessageFiltersManager::removeSelectedFilter);
connect(m_ui.m_txtTitle, &QLineEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter);
connect(m_ui.m_txtScript, &QPlainTextEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter);
connect(m_ui.m_btnTest, &QPushButton::clicked, this, &FormMessageFiltersManager::testFilter);
@ -79,6 +81,17 @@ ServiceRoot* FormMessageFiltersManager::selectedAccount() const {
return dat.isNull() ? nullptr : dat.value<ServiceRoot*>();
}
void FormMessageFiltersManager::removeSelectedFilter() {
auto* fltr = selectedFilter();
if (fltr == nullptr) {
return;
}
m_reader->removeMessageFilter(fltr);
delete m_ui.m_listFilters->currentItem();
}
void FormMessageFiltersManager::loadFilters() {
for (auto* fltr : m_reader->messageFilters()) {
auto* it = new QListWidgetItem(fltr->name(), m_ui.m_listFilters);
@ -88,6 +101,7 @@ void FormMessageFiltersManager::loadFilters() {
}
void FormMessageFiltersManager::addNewFilter() {
try {
auto* fltr = m_reader->addMessageFilter(
tr("New message filter"),
QSL("function filterMessage() { return 1; }"));
@ -97,6 +111,11 @@ void FormMessageFiltersManager::addNewFilter() {
m_ui.m_listFilters->setCurrentRow(m_ui.m_listFilters->count() - 1);
}
catch (const ApplicationException& ex) {
MessageBox::show(this, QMessageBox::Icon::Critical, tr("Error"),
tr("Cannot save new filter, error: ''.").arg(ex.message()));
}
}
void FormMessageFiltersManager::saveSelectedFilter() {
if (m_loadingFilter) {

View File

@ -24,6 +24,7 @@ class FormMessageFiltersManager : public QDialog {
ServiceRoot* selectedAccount() const;
private slots:
void removeSelectedFilter();
void addNewFilter();
void saveSelectedFilter();
void loadFilter();

View File

@ -2,6 +2,7 @@
#include "miscellaneous/databasequeries.h"
#include "exceptions/applicationexception.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/textfactory.h"
@ -26,6 +27,7 @@
#include "services/tt-rss/ttrssfeed.h"
#include "services/tt-rss/ttrssserviceroot.h"
#include <QSqlDriver>
#include <QUrl>
#include <QVariant>
@ -1396,6 +1398,73 @@ bool DatabaseQueries::editBaseFeed(const QSqlDatabase& db, int feed_id, Feed::Au
return q.exec();
}
MessageFilter* DatabaseQueries::addMessageFilter(const QSqlDatabase& db, const QString& title,
const QString& script) {
if (!db.driver()->hasFeature(QSqlDriver::DriverFeature::LastInsertId)) {
throw ApplicationException(QObject::tr("Cannot insert message filter, because current database cannot return last inserted row ID."));
}
QSqlQuery q(db);
q.prepare("INSERT INTO MessageFilters (name, script) VALUES(:name, :script);");
q.bindValue(QSL(":name"), title);
q.bindValue(QSL(":script"), script);
q.setForwardOnly(true);
if (q.exec()) {
auto* fltr = new MessageFilter(q.lastInsertId().toInt());
fltr->setName(title);
fltr->setScript(script);
return fltr;
}
else {
throw ApplicationException(q.lastError().text());
}
}
void DatabaseQueries::removeMessageFilter(const QSqlDatabase& db, int filter_id, bool* ok) {
QSqlQuery q(db);
q.prepare("DELETE FROM MessageFilters WHERE id = :id;");
q.bindValue(QSL(":id"), filter_id);
q.setForwardOnly(true);
if (q.exec()) {
if (ok != nullptr) {
*ok = true;
}
}
else {
if (ok != nullptr) {
*ok = false;
}
}
}
void DatabaseQueries::removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok) {
QSqlQuery q(db);
q.prepare("DELETE FROM MessageFiltersInFeeds WHERE filter = :filter;");
q.bindValue(QSL(":filter"), filter_id);
q.setForwardOnly(true);
if (q.exec()) {
if (ok != nullptr) {
*ok = true;
}
}
else {
if (ok != nullptr) {
*ok = false;
}
}
}
QList<MessageFilter*> DatabaseQueries::getMessageFilters(const QSqlDatabase& db, bool* ok) {
QSqlQuery q(db);
QList<MessageFilter*> filters;

View File

@ -87,6 +87,9 @@ class DatabaseQueries {
int account_id, bool* ok = nullptr);
// Message filters operators.
static MessageFilter* addMessageFilter(const QSqlDatabase& db, const QString& title, const QString& script);
static void removeMessageFilter(const QSqlDatabase& db, int filter_id, bool* ok = nullptr);
static void removeMessageFilterAssignments(const QSqlDatabase& db, int filter_id, bool* ok = nullptr);
static QList<MessageFilter*> getMessageFilters(const QSqlDatabase& db, bool* ok = nullptr);
static QMultiMap<QString, int> messageFiltersInFeeds(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
static void assignMessageFilterToFeed(const QSqlDatabase& db, const QString& feed_custom_id, int filter_id,

View File

@ -150,17 +150,30 @@ void FeedReader::loadSavedMessageFilters() {
}
MessageFilter* FeedReader::addMessageFilter(const QString& title, const QString& script) {
auto* fltr = new MessageFilter(12, this);
fltr->setName(title);
fltr->setScript(script);
// TODO: Save into database, then return.
auto* fltr = DatabaseQueries::addMessageFilter(qApp->database()->connection(metaObject()->className()), title, script);
m_messageFilters.append(fltr);
return fltr;
}
void FeedReader::removeMessageFilter(MessageFilter* filter) {
m_messageFilters.removeAll(filter);
// Now, remove all references from all feeds.
auto all_feeds = m_feedsModel->feedsForIndex();
for (auto* feed : all_feeds) {
feed->removeMessageFilter(filter);
}
// Remove from DB.
DatabaseQueries::removeMessageFilterAssignments(qApp->database()->connection(metaObject()->className()), filter->id());
DatabaseQueries::removeMessageFilter(qApp->database()->connection(metaObject()->className()), filter->id());
// Free from memory as last step.
filter->deleteLater();
}
void FeedReader::updateMessageFilter(MessageFilter* filter) {
DatabaseQueries::updateMessageFilter(qApp->database()->connection(metaObject()->className()), filter);
}

View File

@ -55,6 +55,7 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject {
void loadSavedMessageFilters();
QList<MessageFilter*> messageFilters() const;
MessageFilter* addMessageFilter(const QString& title, const QString& script);
void removeMessageFilter(MessageFilter* filter);
void updateMessageFilter(MessageFilter* filter);
void assignMessageFilterToFeed(Feed* feed, MessageFilter* filter);
void removeMessageFilterToFeedAssignment(Feed* feed, MessageFilter* filter);