diff --git a/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp b/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp index 0fa2fa08d..7e5c19121 100644 --- a/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp +++ b/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp @@ -15,6 +15,7 @@ #include "miscellaneous/iconfactory.h" #include "network-web/webfactory.h" #include "services/abstract/accountcheckmodel.h" +#include "services/abstract/feed.h" FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const QList& accounts, QWidget* parent) : QDialog(parent), m_feedsModel(new AccountCheckModel(this)), m_rootItem(new RootItem()), @@ -45,15 +46,16 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q connect(m_ui.m_txtScript, &QPlainTextEdit::textChanged, this, &FormMessageFiltersManager::saveSelectedFilter); connect(m_ui.m_btnTest, &QPushButton::clicked, this, &FormMessageFiltersManager::testFilter); connect(m_ui.m_btnBeautify, &QPushButton::clicked, this, &FormMessageFiltersManager::beautifyScript); - connect(m_ui.m_cmbAccounts, static_cast(&QComboBox::currentIndexChanged), this, [this]() { - // Load feeds/categories of the account and check marks. - loadSelectedAccount(); - loadFilterFeedAssignments(); - }); + connect(m_ui.m_cmbAccounts, static_cast(&QComboBox::currentIndexChanged), + this, + &FormMessageFiltersManager::onAccountChanged); connect(m_ui.m_btnCheckAll, &QPushButton::clicked, m_feedsModel, &AccountCheckModel::checkAllItems); connect(m_ui.m_btnUncheckAll, &QPushButton::clicked, m_feedsModel, &AccountCheckModel::uncheckAllItems); + connect(m_feedsModel, &AccountCheckModel::checkStateChanged, this, + &FormMessageFiltersManager::onFeedChecked); initializeTestingMessage(); + loadFilters(); loadFilter(); loadAccounts(); } @@ -77,6 +79,14 @@ ServiceRoot* FormMessageFiltersManager::selectedAccount() const { return dat.isNull() ? nullptr : dat.value(); } +void FormMessageFiltersManager::loadFilters() { + for (auto* fltr : m_reader->messageFilters()) { + auto* it = new QListWidgetItem(fltr->name(), m_ui.m_listFilters); + + it->setData(Qt::ItemDataRole::UserRole, QVariant::fromValue(fltr)); + } +} + void FormMessageFiltersManager::addNewFilter() { auto* fltr = m_reader->addMessageFilter( tr("New message filter"), @@ -111,6 +121,7 @@ void FormMessageFiltersManager::loadFilter() { auto* acc = selectedAccount(); showFilter(filter); + loadFilterFeedAssignments(filter, acc); } void FormMessageFiltersManager::testFilter() { @@ -165,12 +176,60 @@ void FormMessageFiltersManager::testFilter() { m_ui.m_tcMessage->setCurrentIndex(1); } -void FormMessageFiltersManager::loadSelectedAccount() { - m_feedsModel->setRootItem(selectedAccount(), false, true); +void FormMessageFiltersManager::loadAccount(ServiceRoot* account) { + m_feedsModel->setRootItem(account, false, true); m_ui.m_treeFeeds->expandAll(); } -void FormMessageFiltersManager::loadFilterFeedAssignments() {} +void FormMessageFiltersManager::loadFilterFeedAssignments(MessageFilter* filter, ServiceRoot* account) { + if (account == nullptr || filter == nullptr) { + return; + } + + m_loadingFilter = true; + + for (auto* feed : account->getSubTreeFeeds()) { + if (feed->messageFilters().contains(filter)) { + m_feedsModel->setItemChecked(feed, Qt::CheckState::Checked); + } + } + + m_loadingFilter = false; +} + +void FormMessageFiltersManager::onAccountChanged() { + // Load feeds/categories of the account and check marks. + auto* filter = selectedFilter(); + auto* acc = selectedAccount(); + + loadAccount(acc); + loadFilterFeedAssignments(filter, acc); +} + +void FormMessageFiltersManager::onFeedChecked(RootItem* item, Qt::CheckState state) { + if (m_loadingFilter) { + return; + } + + auto* feed = qobject_cast(item); + + if (feed == nullptr) { + return; + } + + switch (state) { + case Qt::CheckState::Checked: + m_reader->assignMessageFilterToFeed(feed, selectedFilter()); + break; + + case Qt::CheckState::Unchecked: + m_reader->removeMessageFilterToFeedAssignment(feed, selectedFilter()); + break; + + case Qt::CheckState::PartiallyChecked: + break; + } +} void FormMessageFiltersManager::showFilter(MessageFilter* filter) { m_loadingFilter = true; diff --git a/src/librssguard/gui/dialogs/formmessagefiltersmanager.h b/src/librssguard/gui/dialogs/formmessagefiltersmanager.h index 1f1e16d58..ee32d2392 100644 --- a/src/librssguard/gui/dialogs/formmessagefiltersmanager.h +++ b/src/librssguard/gui/dialogs/formmessagefiltersmanager.h @@ -27,13 +27,17 @@ class FormMessageFiltersManager : public QDialog { void addNewFilter(); void saveSelectedFilter(); void loadFilter(); + void loadFilters(); void testFilter(); // Load feeds/categories tree. - void loadSelectedAccount(); + void loadAccount(ServiceRoot* account); // Load checkmarks according to already active assignments. - void loadFilterFeedAssignments(); + void loadFilterFeedAssignments(MessageFilter* filter, ServiceRoot* account); + + void onAccountChanged(); + void onFeedChecked(RootItem* item, Qt::CheckState state); // Display filter title/contents. void showFilter(MessageFilter* filter); diff --git a/src/librssguard/miscellaneous/feedreader.cpp b/src/librssguard/miscellaneous/feedreader.cpp index aff7fcd70..c2ad1227a 100644 --- a/src/librssguard/miscellaneous/feedreader.cpp +++ b/src/librssguard/miscellaneous/feedreader.cpp @@ -167,6 +167,18 @@ void FeedReader::updateMessageFilter(MessageFilter* filter) { // TODO: Filter's name or script is changed, save to database. } +void FeedReader::assignMessageFilterToFeed(Feed* feed, MessageFilter* filter) { + feed->appendMessageFilter(filter); + + // TODO: Add assignment to database. +} + +void FeedReader::removeMessageFilterToFeedAssignment(Feed* feed, MessageFilter* filter) { + feed->removeMessageFilter(filter); + + // TODO: Remove assignment from database. +} + void FeedReader::updateAllFeeds() { updateFeeds(m_feedsModel->rootItem()->getSubTreeFeeds()); } diff --git a/src/librssguard/miscellaneous/feedreader.h b/src/librssguard/miscellaneous/feedreader.h index 4bc375a90..dd8080c8f 100644 --- a/src/librssguard/miscellaneous/feedreader.h +++ b/src/librssguard/miscellaneous/feedreader.h @@ -56,6 +56,8 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject { QList messageFilters() const; MessageFilter* addMessageFilter(const QString& title, const QString& script); void updateMessageFilter(MessageFilter* filter); + void assignMessageFilterToFeed(Feed* feed, MessageFilter* filter); + void removeMessageFilterToFeedAssignment(Feed* feed, MessageFilter* filter); public slots: void updateAllFeeds(); diff --git a/src/librssguard/services/abstract/accountcheckmodel.cpp b/src/librssguard/services/abstract/accountcheckmodel.cpp index b686a44c2..f0852aafe 100644 --- a/src/librssguard/services/abstract/accountcheckmodel.cpp +++ b/src/librssguard/services/abstract/accountcheckmodel.cpp @@ -229,18 +229,28 @@ bool AccountCheckModel::setData(const QModelIndex& index, const QVariant& value, item = item->parent(); // Check children of this new parent item. - Qt::CheckState parent_state = Qt::Unchecked; + bool all_checked = true; + bool all_unchecked = true; for (RootItem* child_of_parent : item->childItems()) { - if (m_checkStates.contains(child_of_parent) && m_checkStates[child_of_parent] == Qt::Checked) { - // We found out, that some child of this item is checked, - // therefore this item must be checked too. - parent_state = Qt::Checked; - break; + if (m_checkStates.contains(child_of_parent)) { + all_checked &= m_checkStates[child_of_parent] == Qt::CheckState::Checked; + all_unchecked &= m_checkStates[child_of_parent] == Qt::CheckState::Unchecked; + } + else { + all_checked = false; } } - setData(parent_index, parent_state, Qt::CheckStateRole); + if (all_checked) { + setData(parent_index, Qt::CheckState::Checked, Qt::CheckStateRole); + } + else if (all_unchecked) { + setData(parent_index, Qt::CheckState::Unchecked, Qt::CheckStateRole); + } + else { + setData(parent_index, Qt::CheckState::PartiallyChecked, Qt::CheckStateRole); + } } m_recursiveChange = false; diff --git a/src/librssguard/services/abstract/accountcheckmodel.h b/src/librssguard/services/abstract/accountcheckmodel.h index f11e027bd..13bee3533 100644 --- a/src/librssguard/services/abstract/accountcheckmodel.h +++ b/src/librssguard/services/abstract/accountcheckmodel.h @@ -44,7 +44,7 @@ class AccountCheckModel : public QAbstractItemModel { void uncheckAllItems(); signals: - void checkStateChanged(RootItem* item, Qt::CheckState); + void checkStateChanged(RootItem* item, Qt::CheckState state); protected: RootItem* m_rootItem; diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 1de515805..1c43ab6d9 100755 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -52,7 +52,7 @@ Feed::Feed(const Feed& other) : RootItem(other) { setAutoUpdateType(other.autoUpdateType()); setAutoUpdateInitialInterval(other.autoUpdateInitialInterval()); setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval()); - setFilters(other.messageFilters()); + setMessageFilters(other.messageFilters()); } Feed::~Feed() = default; @@ -288,10 +288,20 @@ QList> Feed::messageFilters() const { return m_messageFilters; } -void Feed::setFilters(const QList>& filters) { +void Feed::setMessageFilters(const QList>& filters) { m_messageFilters = filters; } +void Feed::removeMessageFilter(MessageFilter* filter) { + // TODO: check this. + + int idx = m_messageFilters.indexOf(filter); + + if (idx >= 0) { + m_messageFilters.removeAll(filter); + } +} + QString Feed::additionalTooltip() const { return tr("Auto-update status: %1\n" "Active message filters: %2\n" diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index 1b9edcffe..dffef60c7 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -71,7 +71,8 @@ class Feed : public RootItem { void appendMessageFilter(MessageFilter* filter); QList> messageFilters() const; - void setFilters(const QList>& messageFilters); + void setMessageFilters(const QList>& messageFilters); + void removeMessageFilter(MessageFilter* filter); bool markAsReadUnread(ReadStatus status); bool cleanMessages(bool clean_read_only);