diff --git a/src/librssguard/gui/feedsview.cpp b/src/librssguard/gui/feedsview.cpp index dbdecdc09..2b232fd1d 100755 --- a/src/librssguard/gui/feedsview.cpp +++ b/src/librssguard/gui/feedsview.cpp @@ -673,6 +673,8 @@ QMenu* FeedsView::initializeContextMenuLabel(RootItem* clicked_item) { } else { m_contextMenuLabel->addAction(qApp->mainForm()->m_ui->m_actionEditSelectedItem); + m_contextMenuLabel->addAction(qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead); + m_contextMenuLabel->addAction(qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread); m_contextMenuLabel->addAction(qApp->mainForm()->m_ui->m_actionDeleteSelectedItem); } diff --git a/src/librssguard/miscellaneous/databasequeries.cpp b/src/librssguard/miscellaneous/databasequeries.cpp index d7f8b572e..0cfcf4908 100755 --- a/src/librssguard/miscellaneous/databasequeries.cpp +++ b/src/librssguard/miscellaneous/databasequeries.cpp @@ -196,6 +196,23 @@ bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int acco return q.exec() && res; } +bool DatabaseQueries::markLabelledMessagesReadUnread(const QSqlDatabase& db, Label* label, RootItem::ReadStatus read) { + QSqlQuery q(db); + + q.setForwardOnly(true); + q.prepare("UPDATE Messages SET is_read = :read " + "WHERE " + " is_deleted = 0 AND " + " is_pdeleted = 0 AND " + " account_id = :account_id AND " + " EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);"); + q.bindValue(QSL(":read"), read == RootItem::ReadStatus::Read ? 1 : 0); + q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId()); + q.bindValue(QSL(":label"), label->customId()); + + return q.exec(); +} + bool DatabaseQueries::markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read) { QSqlQuery q(db); @@ -1329,6 +1346,34 @@ QStringList DatabaseQueries::customIdsOfMessagesFromAccount(const QSqlDatabase& return ids; } +QStringList DatabaseQueries::customIdsOfMessagesFromLabel(const QSqlDatabase& db, Label* label, bool* ok) { + QSqlQuery q(db); + QStringList ids; + + q.setForwardOnly(true); + q.prepare(QSL("SELECT custom_id FROM Messages " + "WHERE " + " is_deleted = 0 AND " + " is_pdeleted = 0 AND " + " account_id = :account_id AND " + " EXISTS (SELECT * FROM LabelsInMessages WHERE LabelsInMessages.label = :label AND Messages.account_id = LabelsInMessages.account_id AND Messages.custom_id = LabelsInMessages.message);")); + q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId()); + q.bindValue(QSL(":label"), label->customId()); + + if (ok != nullptr) { + *ok = q.exec(); + } + else { + q.exec(); + } + + while (q.next()) { + ids.append(q.value(0).toString()); + } + + return ids; +} + QStringList DatabaseQueries::customIdsOfImportantMessages(const QSqlDatabase& db, int account_id, bool* ok) { QSqlQuery q(db); QStringList ids; diff --git a/src/librssguard/miscellaneous/databasequeries.h b/src/librssguard/miscellaneous/databasequeries.h index da1f103b9..98beefacc 100644 --- a/src/librssguard/miscellaneous/databasequeries.h +++ b/src/librssguard/miscellaneous/databasequeries.h @@ -29,6 +29,7 @@ class DatabaseQueries { static bool createLabel(const QSqlDatabase& db, Label* label, 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); static bool markMessagesReadUnread(const QSqlDatabase& db, const QStringList& ids, RootItem::ReadStatus read); static bool markMessageImportant(const QSqlDatabase& db, int id, RootItem::Importance importance); @@ -79,6 +80,7 @@ class DatabaseQueries { static QList getUndeletedMessagesForAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr); // Custom ID accumulators. + static QStringList customIdsOfMessagesFromLabel(const QSqlDatabase& db, Label* label, bool* ok = nullptr); static QStringList customIdsOfImportantMessages(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QStringList customIdsOfMessagesFromAccount(const QSqlDatabase& db, int account_id, bool* ok = nullptr); static QStringList customIdsOfMessagesFromBin(const QSqlDatabase& db, int account_id, bool* ok = nullptr); diff --git a/src/librssguard/services/abstract/label.cpp b/src/librssguard/services/abstract/label.cpp index fbb90da14..841b67cd9 100755 --- a/src/librssguard/services/abstract/label.cpp +++ b/src/librssguard/services/abstract/label.cpp @@ -6,6 +6,7 @@ #include "miscellaneous/application.h" #include "miscellaneous/databasefactory.h" #include "miscellaneous/databasequeries.h" +#include "services/abstract/cacheforserviceroot.h" #include "services/abstract/serviceroot.h" #include @@ -124,3 +125,24 @@ void Label::setCountOfAllMessages(int totalCount) { void Label::setCountOfUnreadMessages(int unreadCount) { m_unreadCount = unreadCount; } + +bool Label::markAsReadUnread(RootItem::ReadStatus status) { + ServiceRoot* service = getParentServiceRoot(); + auto* cache = dynamic_cast(service); + + if (cache != nullptr) { + cache->addMessageStatesToCache(service->customIDSOfMessagesForItem(this), status); + } + + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); + + if (DatabaseQueries::markLabelledMessagesReadUnread(database, this, status)) { + service->updateCounts(true); + service->itemChanged(getSubTree()); + service->requestReloadMessageList(status == RootItem::ReadStatus::Read); + return true; + } + else { + return false; + } +} diff --git a/src/librssguard/services/abstract/label.h b/src/librssguard/services/abstract/label.h index 182089b76..1676cd8e3 100755 --- a/src/librssguard/services/abstract/label.h +++ b/src/librssguard/services/abstract/label.h @@ -20,6 +20,7 @@ class Label : public RootItem { void setCountOfAllMessages(int totalCount); void setCountOfUnreadMessages(int unreadCount); + virtual bool markAsReadUnread(ReadStatus status); virtual int countOfAllMessages() const; virtual int countOfUnreadMessages() const; virtual bool canBeEdited() const; diff --git a/src/librssguard/services/abstract/rootitem.cpp b/src/librssguard/services/abstract/rootitem.cpp index 6b8ea2c20..61e91d641 100644 --- a/src/librssguard/services/abstract/rootitem.cpp +++ b/src/librssguard/services/abstract/rootitem.cpp @@ -80,7 +80,9 @@ QList RootItem::undeletedMessages() const { QList messages; for (RootItem* child : m_childItems) { - messages.append(child->undeletedMessages()); + if (child->kind() != RootItem::Kind::Bin) { + messages.append(child->undeletedMessages()); + } } return messages; diff --git a/src/librssguard/services/abstract/rootitem.h b/src/librssguard/services/abstract/rootitem.h index 2f792ce97..41752fae9 100644 --- a/src/librssguard/services/abstract/rootitem.h +++ b/src/librssguard/services/abstract/rootitem.h @@ -86,6 +86,7 @@ class RSSGUARD_DLLSPEC RootItem : public QObject { // This method should "clean" all messages it contains. // What "clean" means? It means delete messages -> move them to recycle bin // or eventually remove them completely if there is no recycle bin functionality. + // // If this method is called on "recycle bin" instance of your // service account, it should "empty" the recycle bin. virtual bool cleanMessages(bool clear_only_read); diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 2e3d1604a..63249ffac 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -106,7 +106,9 @@ void ServiceRoot::updateCounts(bool including_total_count) { if (child->kind() == RootItem::Kind::Feed) { feeds.append(child->toFeed()); } - else if (child->kind() != RootItem::Kind::Category && child->kind() != RootItem::Kind::ServiceRoot) { + else if (child->kind() != RootItem::Kind::Labels && + child->kind() != RootItem::Kind::Category && + child->kind() != RootItem::Kind::ServiceRoot) { child->updateCounts(including_total_count); } } @@ -400,6 +402,7 @@ QStringList ServiceRoot::customIDSOfMessagesForItem(RootItem* item) { QStringList list; switch (item->kind()) { + case RootItem::Kind::Labels: case RootItem::Kind::Category: { for (RootItem* child : item->childItems()) { list.append(customIDSOfMessagesForItem(child)); @@ -408,6 +411,13 @@ QStringList ServiceRoot::customIDSOfMessagesForItem(RootItem* item) { return list; } + case RootItem::Kind::Label: { + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); + + list = DatabaseQueries::customIdsOfMessagesFromLabel(database, item->toLabel()); + break; + } + case RootItem::Kind::ServiceRoot: { QSqlDatabase database = qApp->database()->connection(metaObject()->className());