Fix indeterminate state in AccountsCheckModel, add logic for add/remove filter/feed assignments.

This commit is contained in:
Martin Rotter 2020-07-09 08:35:36 +02:00
parent 032fccc387
commit 4fbe103d41
8 changed files with 119 additions and 21 deletions

View file

@ -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<ServiceRoot*>& 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<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [this]() {
// Load feeds/categories of the account and check marks.
loadSelectedAccount();
loadFilterFeedAssignments();
});
connect(m_ui.m_cmbAccounts, static_cast<void (QComboBox::*)(int)>(&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<ServiceRoot*>();
}
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<MessageFilter*>(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<Feed*>(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;

View file

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

View file

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

View file

@ -56,6 +56,8 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject {
QList<MessageFilter*> 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();

View file

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

View file

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

View file

@ -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<QPointer<MessageFilter>> Feed::messageFilters() const {
return m_messageFilters;
}
void Feed::setFilters(const QList<QPointer<MessageFilter>>& filters) {
void Feed::setMessageFilters(const QList<QPointer<MessageFilter>>& 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"

View file

@ -71,7 +71,8 @@ class Feed : public RootItem {
void appendMessageFilter(MessageFilter* filter);
QList<QPointer<MessageFilter>> messageFilters() const;
void setFilters(const QList<QPointer<MessageFilter>>& messageFilters);
void setMessageFilters(const QList<QPointer<MessageFilter>>& messageFilters);
void removeMessageFilter(MessageFilter* filter);
bool markAsReadUnread(ReadStatus status);
bool cleanMessages(bool clean_read_only);