Support mark read/unread action for "label" items.

This commit is contained in:
Martin Rotter 2020-10-19 19:29:00 +02:00
parent 6ed79f5133
commit 02ffa583c3
8 changed files with 87 additions and 2 deletions

View File

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

View File

@ -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;

View File

@ -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<Message> 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);

View File

@ -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 <QPainter>
@ -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<CacheForServiceRoot*>(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;
}
}

View File

@ -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;

View File

@ -80,8 +80,10 @@ QList<Message> RootItem::undeletedMessages() const {
QList<Message> messages;
for (RootItem* child : m_childItems) {
if (child->kind() != RootItem::Kind::Bin) {
messages.append(child->undeletedMessages());
}
}
return messages;
}

View File

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

View File

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