diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index c0e1f6b36..01ee5d9bf 100644 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -288,6 +288,55 @@ bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int acco return q.exec() && res; } +void DatabaseQueries::createProbe(const QSqlDatabase& db, Search* probe, int account_id) { + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare(QSL("INSERT INTO Probes (name, color, fltr, account_id) " + "VALUES (:name, :color, :fltr, :account_id);")); + q.bindValue(QSL(":name"), probe->title()); + q.bindValue(QSL(":fltr"), probe->filter()); + q.bindValue(QSL(":color"), probe->color().name()); + q.bindValue(QSL(":account_id"), account_id); + + auto res = q.exec(); + + if (res && q.lastInsertId().isValid()) { + probe->setId(q.lastInsertId().toInt()); + probe->setCustomId(QString::number(probe->id())); + } + else { + throw ApplicationException(q.lastError().text()); + } +} + +QList DatabaseQueries::getProbesForAccount(const QSqlDatabase& db, int account_id) { + QList probes; + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare(QSL("SELECT * FROM Probes WHERE account_id = :account_id;")); + q.bindValue(QSL(":account_id"), account_id); + + if (q.exec()) { + while (q.next()) { + Search* prob = new Search(q.value(QSL("name")).toString(), + q.value(QSL("fltr")).toString(), + QColor(q.value(QSL("color")).toString())); + + prob->setId(q.value(QSL("id")).toInt()); + prob->setCustomId(QString::number(prob->id())); + + probes << prob; + } + } + else { + throw ApplicationException(q.lastError().text()); + } + + return probes; +} + bool DatabaseQueries::markLabelledMessagesReadUnread(const QSqlDatabase& db, Label* label, RootItem::ReadStatus read) { QSqlQuery q(db); diff --git a/src/librssguard/database/databasequeries.h b/src/librssguard/database/databasequeries.h index f9faab2c4..0b9202393 100644 --- a/src/librssguard/database/databasequeries.h +++ b/src/librssguard/database/databasequeries.h @@ -12,6 +12,7 @@ #include "miscellaneous/textfactory.h" #include "services/abstract/category.h" #include "services/abstract/label.h" +#include "services/abstract/search.h" #include "services/abstract/serviceroot.h" #include @@ -46,6 +47,10 @@ class DatabaseQueries { static bool deleteLabel(const QSqlDatabase& db, Label* label); static bool createLabel(const QSqlDatabase& db, Label* label, int account_id); + // Probe operators. + static void createProbe(const QSqlDatabase& db, Search* probe, int account_id); + static QList getProbesForAccount(const QSqlDatabase& db, int account_id); + // Message operators. static bool markLabelledMessagesReadUnread(const QSqlDatabase& db, Label* label, RootItem::ReadStatus read); static bool markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read); @@ -143,7 +148,8 @@ class DatabaseQueries { template static QList getAccounts(const QSqlDatabase& db, const QString& code, bool* ok = nullptr); - template static void loadRootFromDatabase(ServiceRoot* root); + template + static void loadRootFromDatabase(ServiceRoot* root); static bool storeNewOauthTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id); static void createOverwriteAccount(const QSqlDatabase& db, ServiceRoot* account); @@ -169,7 +175,8 @@ class DatabaseQueries { static bool deleteFeed(const QSqlDatabase& db, Feed* feed, int account_id); static bool deleteCategory(const QSqlDatabase& db, Category* category); - template static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr); + template + static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr); template static Assignment getFeeds(const QSqlDatabase& db, @@ -249,7 +256,8 @@ QList DatabaseQueries::getAccounts(const QSqlDatabase& db, const Q return roots; } -template Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id, bool* ok) { +template +Assignment DatabaseQueries::getCategories(const QSqlDatabase& db, int account_id, bool* ok) { Assignment categories; // Obtain data for categories from the database. @@ -381,13 +389,15 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db, return feeds; } -template void DatabaseQueries::loadRootFromDatabase(ServiceRoot* root) { +template +void DatabaseQueries::loadRootFromDatabase(ServiceRoot* root) { QSqlDatabase database = qApp->database()->driver()->connection(root->metaObject()->className()); Assignment categories = DatabaseQueries::getCategories(database, root->accountId()); Assignment feeds = DatabaseQueries::getFeeds(database, qApp->feedReader()->messageFilters(), root->accountId()); auto labels = DatabaseQueries::getLabelsForAccount(database, root->accountId()); + auto probes = DatabaseQueries::getProbesForAccount(database, root->accountId()); - root->performInitialAssembly(categories, feeds, labels); + root->performInitialAssembly(categories, feeds, labels, probes); } #endif // DATABASEQUERIES_H diff --git a/src/librssguard/gui/feedsview.cpp b/src/librssguard/gui/feedsview.cpp index 944e0e4f1..d946939fe 100644 --- a/src/librssguard/gui/feedsview.cpp +++ b/src/librssguard/gui/feedsview.cpp @@ -601,8 +601,8 @@ void FeedsView::onIndexExpanded(const QModelIndex& idx) { const RootItem* it = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(idx)); - if (it != nullptr && - (int(it->kind()) & int(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | RootItem::Kind::Labels)) > 0) { + if (it != nullptr && (int(it->kind()) & int(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels | RootItem::Kind::Probes)) > 0) { const QString setting_name = it->hashCode(); qApp->settings()->setValue(GROUP(CategoriesExpandStates), setting_name, true); @@ -619,8 +619,8 @@ void FeedsView::onIndexCollapsed(const QModelIndex& idx) { RootItem* it = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(idx)); - if (it != nullptr && - (int(it->kind()) & int(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | RootItem::Kind::Labels)) > 0) { + if (it != nullptr && (int(it->kind()) & int(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels | RootItem::Kind::Probes)) > 0) { const QString setting_name = it->hashCode(); qApp->settings()->setValue(GROUP(CategoriesExpandStates), setting_name, false); @@ -637,8 +637,8 @@ void FeedsView::saveAllExpandStates() { void FeedsView::saveExpandStates(RootItem* item) { Settings* settings = qApp->settings(); - QList items = - item->getSubTree(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | RootItem::Kind::Labels); + QList items = item->getSubTree(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | + RootItem::Kind::Labels | RootItem::Kind::Probes); // Iterate all categories and save their expand statuses. for (const RootItem* it : items) { @@ -655,7 +655,7 @@ void FeedsView::loadAllExpandStates() { QList expandable_items; expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItem::Kind::Category | RootItem::Kind::ServiceRoot | - RootItem::Kind::Labels)); + RootItem::Kind::Labels | RootItem::Kind::Probes)); // Iterate all categories and save their expand statuses. for (const RootItem* item : expandable_items) { diff --git a/src/librssguard/services/abstract/gui/formaddeditprobe.cpp b/src/librssguard/services/abstract/gui/formaddeditprobe.cpp index 7aa5ddb6e..f932178e7 100755 --- a/src/librssguard/services/abstract/gui/formaddeditprobe.cpp +++ b/src/librssguard/services/abstract/gui/formaddeditprobe.cpp @@ -14,15 +14,16 @@ FormAddEditProbe::FormAddEditProbe(QWidget* parent) : QDialog(parent), m_editabl connect(m_ui.m_txtName->lineEdit(), &QLineEdit::textChanged, this, [this](const QString& text) { if (text.isEmpty()) { - m_ui.m_txtName->setStatus(LineEditWithStatus::StatusType::Error, tr("Label's name cannot be empty.")); + m_ui.m_txtName->setStatus(LineEditWithStatus::StatusType::Error, tr("Probe name cannot be empty.")); } else { m_ui.m_txtName->setStatus(LineEditWithStatus::StatusType::Ok, tr("Perfect!")); } }); + connect(m_ui.m_txtFilter->lineEdit(), &QLineEdit::textChanged, this, [this](const QString& text) { if (text.isEmpty()) { - m_ui.m_txtFilter->setStatus(LineEditWithStatus::StatusType::Error, tr("Probe name cannot be empty.")); + m_ui.m_txtFilter->setStatus(LineEditWithStatus::StatusType::Error, tr("Probe filter cannot be empty.")); } else if (!QRegularExpression(text).isValid()) { m_ui.m_txtFilter->setStatus(LineEditWithStatus::StatusType::Error, tr("Regular expression is not well-formed.")); diff --git a/src/librssguard/services/abstract/labelsnode.cpp b/src/librssguard/services/abstract/labelsnode.cpp index bb2fafd47..361e7e315 100644 --- a/src/librssguard/services/abstract/labelsnode.cpp +++ b/src/librssguard/services/abstract/labelsnode.cpp @@ -132,6 +132,7 @@ void LabelsNode::createLabel() { DatabaseQueries::createLabel(db, new_lbl, getParentServiceRoot()->accountId()); getParentServiceRoot()->requestItemReassignment(new_lbl, this); + getParentServiceRoot()->requestItemExpand({this}, true); } catch (const ApplicationException&) { new_lbl->deleteLater(); diff --git a/src/librssguard/services/abstract/searchsnode.cpp b/src/librssguard/services/abstract/searchsnode.cpp index bfd85a92c..6bcc93e52 100755 --- a/src/librssguard/services/abstract/searchsnode.cpp +++ b/src/librssguard/services/abstract/searchsnode.cpp @@ -128,9 +128,10 @@ void SearchsNode::createProbe() { QSqlDatabase db = qApp->database()->driver()->connection(metaObject()->className()); try { - // DatabaseQueries::createLabel(db, new_prb, getParentServiceRoot()->accountId()); + DatabaseQueries::createProbe(db, new_prb, getParentServiceRoot()->accountId()); getParentServiceRoot()->requestItemReassignment(new_prb, this); + getParentServiceRoot()->requestItemExpand({this}, true); } catch (const ApplicationException&) { new_prb->deleteLater(); diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index fc1e29219..e358f821a 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -565,10 +565,13 @@ void ServiceRoot::syncIn() { void ServiceRoot::performInitialAssembly(const Assignment& categories, const Assignment& feeds, - const QList& labels) { + const QList& labels, + const QList& probes) { assembleCategories(categories); assembleFeeds(feeds); labelsNode()->loadLabels(labels); + probesNode()->loadProbes(probes); + updateCounts(true); } diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index 384cdc91d..054d37c12 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -43,7 +43,11 @@ class ServiceRoot : public RootItem { Synchronised = 8 }; - enum class BagOfMessages { Read, Unread, Starred }; + enum class BagOfMessages { + Read, + Unread, + Starred + }; public: explicit ServiceRoot(RootItem* parent = nullptr); @@ -235,7 +239,10 @@ class ServiceRoot : public RootItem { QStringList customIDSOfMessagesForItem(RootItem* item, RootItem::ReadStatus target_read = RootItem::ReadStatus::Unknown); - void performInitialAssembly(const Assignment& categories, const Assignment& feeds, const QList& labels); + void performInitialAssembly(const Assignment& categories, + const Assignment& feeds, + const QList& labels, + const QList& probes); public slots: virtual void addNewFeed(RootItem* selected_item, const QString& url = QString());