mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-02-06 20:33:38 +01:00
Sort cats/feeds in export/import model and in msg filter dialog.
This commit is contained in:
parent
ebc7634ffc
commit
e2198faedc
@ -18,7 +18,7 @@
|
||||
#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()),
|
||||
: QDialog(parent), m_feedsModel(new AccountCheckSortedModel(this)), m_rootItem(new RootItem()),
|
||||
m_accounts(accounts), m_reader(reader), m_loadingFilter(false) {
|
||||
m_ui.setupUi(this);
|
||||
|
||||
@ -51,10 +51,10 @@ FormMessageFiltersManager::FormMessageFiltersManager(FeedReader* reader, const Q
|
||||
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);
|
||||
connect(m_ui.m_btnCheckAll, &QPushButton::clicked, m_feedsModel->sourceModel(), &AccountCheckModel::checkAllItems);
|
||||
connect(m_ui.m_btnUncheckAll, &QPushButton::clicked, m_feedsModel->sourceModel(), &AccountCheckModel::uncheckAllItems);
|
||||
connect(m_feedsModel->sourceModel(), &AccountCheckModel::checkStateChanged,
|
||||
this, &FormMessageFiltersManager::onFeedChecked);
|
||||
|
||||
initializeTestingMessage();
|
||||
loadFilters();
|
||||
@ -211,7 +211,7 @@ void FormMessageFiltersManager::loadFilterFeedAssignments(MessageFilter* filter,
|
||||
|
||||
for (auto* feed : account->getSubTreeFeeds()) {
|
||||
if (feed->messageFilters().contains(filter)) {
|
||||
m_feedsModel->setItemChecked(feed, Qt::CheckState::Checked);
|
||||
m_feedsModel->sourceModel()->setItemChecked(feed, Qt::CheckState::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "ui_formmessagefiltersmanager.h"
|
||||
|
||||
class AccountCheckModel;
|
||||
class AccountCheckSortedModel;
|
||||
class MessageFilter;
|
||||
class FeedReader;
|
||||
|
||||
@ -51,7 +51,7 @@ class FormMessageFiltersManager : public QDialog {
|
||||
|
||||
private:
|
||||
Ui::FormMessageFiltersManager m_ui;
|
||||
AccountCheckModel* m_feedsModel;
|
||||
AccountCheckSortedModel* m_feedsModel;
|
||||
RootItem* m_rootItem;
|
||||
QList<ServiceRoot*> m_accounts;
|
||||
FeedReader* m_reader;
|
||||
|
@ -193,9 +193,6 @@ void Application::eliminateFirstRuns() {
|
||||
|
||||
void Application::setFeedReader(FeedReader* feed_reader) {
|
||||
m_feedReader = feed_reader;
|
||||
|
||||
connect(m_feedReader, &FeedReader::feedUpdatesStarted, this, &Application::onFeedUpdatesStarted);
|
||||
connect(m_feedReader, &FeedReader::feedUpdatesProgress, this, &Application::onFeedUpdatesProgress);
|
||||
connect(m_feedReader, &FeedReader::feedUpdatesFinished, this, &Application::onFeedUpdatesFinished);
|
||||
}
|
||||
|
||||
@ -505,14 +502,6 @@ void Application::downloadRequested(QWebEngineDownloadItem* download_item) {
|
||||
|
||||
#endif
|
||||
|
||||
void Application::onFeedUpdatesStarted() {}
|
||||
|
||||
void Application::onFeedUpdatesProgress(const Feed* feed, int current, int total) {
|
||||
Q_UNUSED(feed)
|
||||
Q_UNUSED(current)
|
||||
Q_UNUSED(total)
|
||||
}
|
||||
|
||||
void Application::onFeedUpdatesFinished(const FeedDownloadResults& results) {
|
||||
if (!results.updatedFeeds().isEmpty()) {
|
||||
// Now, inform about results via GUI message/notification.
|
||||
|
@ -133,8 +133,6 @@ class RSSGUARD_DLLSPEC Application : public QtSingleApplication {
|
||||
void downloadRequested(QWebEngineDownloadItem* download_item);
|
||||
#endif
|
||||
|
||||
void onFeedUpdatesStarted();
|
||||
void onFeedUpdatesProgress(const Feed* feed, int current, int total);
|
||||
void onFeedUpdatesFinished(const FeedDownloadResults& results);
|
||||
|
||||
private:
|
||||
|
@ -280,3 +280,71 @@ bool AccountCheckModel::isItemChecked(RootItem* item) {
|
||||
bool AccountCheckModel::setItemChecked(RootItem* item, Qt::CheckState check) {
|
||||
return setData(indexForItem(item), check, Qt::CheckStateRole);
|
||||
}
|
||||
|
||||
AccountCheckSortedModel::AccountCheckSortedModel(QObject* parent)
|
||||
: QSortFilterProxyModel(parent), m_sourceModel(new AccountCheckModel(parent)) {
|
||||
setDynamicSortFilter(false);
|
||||
setSourceModel(m_sourceModel);
|
||||
sort(0, Qt::SortOrder::AscendingOrder);
|
||||
}
|
||||
|
||||
bool AccountCheckSortedModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const {
|
||||
auto* lhs = m_sourceModel->itemForIndex(source_left);
|
||||
auto* rhs = m_sourceModel->itemForIndex(source_right);
|
||||
|
||||
if (lhs != nullptr && rhs != nullptr) {
|
||||
QList<RootItem::Kind> priorities = {
|
||||
RootItem::Kind::Category,
|
||||
RootItem::Kind::Feed,
|
||||
RootItem::Kind::Labels,
|
||||
RootItem::Kind::Important,
|
||||
RootItem::Kind::Bin
|
||||
};
|
||||
|
||||
if (lhs->keepOnTop()) {
|
||||
return sortOrder() == Qt::SortOrder::AscendingOrder;
|
||||
}
|
||||
else if (rhs->keepOnTop()) {
|
||||
return sortOrder() == Qt::SortOrder::DescendingOrder;
|
||||
}
|
||||
|
||||
auto left_priority = priorities.indexOf(lhs->kind());
|
||||
auto right_priority = priorities.indexOf(rhs->kind());
|
||||
|
||||
if (left_priority == right_priority) {
|
||||
return QString::localeAwareCompare(lhs->title().toLower(), rhs->title().toLower()) < 0;
|
||||
}
|
||||
else {
|
||||
return sortOrder() == Qt::SortOrder::AscendingOrder
|
||||
? left_priority < right_priority
|
||||
: right_priority < left_priority;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AccountCheckModel* AccountCheckSortedModel::sourceModel() const {
|
||||
return m_sourceModel;
|
||||
}
|
||||
|
||||
void AccountCheckSortedModel::setRootItem(RootItem* root_item, bool delete_previous_root, bool with_layout_change) {
|
||||
setSourceModel(nullptr);
|
||||
m_sourceModel->setRootItem(root_item, delete_previous_root, with_layout_change);
|
||||
setSourceModel(m_sourceModel);
|
||||
}
|
||||
|
||||
void AccountCheckSortedModel::checkAllItems() {
|
||||
m_sourceModel->checkAllItems();
|
||||
}
|
||||
|
||||
void AccountCheckSortedModel::uncheckAllItems() {
|
||||
m_sourceModel->uncheckAllItems();
|
||||
}
|
||||
|
||||
bool AccountCheckSortedModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
|
||||
auto kind = m_sourceModel->itemForIndex(m_sourceModel->index(source_row, 0, source_parent))->kind();
|
||||
|
||||
return kind == RootItem::Kind::Root || kind == RootItem::Kind::ServiceRoot ||
|
||||
kind == RootItem::Kind::Category || kind == RootItem::Kind::Feed;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#define ACCOUNTCHECKMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "services/abstract/rootitem.h"
|
||||
|
||||
@ -54,4 +55,26 @@ class AccountCheckModel : public QAbstractItemModel {
|
||||
bool m_recursiveChange;
|
||||
};
|
||||
|
||||
class AccountCheckSortedModel : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AccountCheckSortedModel(QObject* parent = nullptr);
|
||||
virtual ~AccountCheckSortedModel() = default;
|
||||
|
||||
AccountCheckModel* sourceModel() const;
|
||||
void setRootItem(RootItem* root_item, bool delete_previous_root = true, bool with_layout_change = false);
|
||||
|
||||
public slots:
|
||||
void checkAllItems();
|
||||
void uncheckAllItems();
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
|
||||
virtual bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const;
|
||||
|
||||
private:
|
||||
AccountCheckModel* m_sourceModel;
|
||||
};
|
||||
|
||||
#endif // ACCOUNTCHECKMODEL_H
|
||||
|
@ -16,13 +16,13 @@
|
||||
#include <QStack>
|
||||
|
||||
FeedsImportExportModel::FeedsImportExportModel(QObject* parent)
|
||||
: AccountCheckModel(parent), m_mode(Mode::Import) {}
|
||||
: AccountCheckSortedModel(parent), m_mode(Mode::Import) {}
|
||||
|
||||
FeedsImportExportModel::~FeedsImportExportModel() {
|
||||
if (m_rootItem != nullptr && m_mode == Mode::Import) {
|
||||
if (sourceModel() != nullptr && sourceModel()->rootItem() != nullptr && m_mode == Mode::Import) {
|
||||
// Delete all model items, but only if we are in import mode. Export mode shares
|
||||
// root item with main feed model, thus cannot be deleted from memory now.
|
||||
delete m_rootItem;
|
||||
delete sourceModel()->rootItem();
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray& result) {
|
||||
QDomElement elem_opml_body = opml_document.createElement(QSL("body"));
|
||||
QStack<RootItem*> items_to_process;
|
||||
|
||||
items_to_process.push(m_rootItem);
|
||||
items_to_process.push(sourceModel()->rootItem());
|
||||
QStack<QDomElement> elements_to_use;
|
||||
|
||||
elements_to_use.push(elem_opml_body);
|
||||
@ -65,7 +65,7 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray& result) {
|
||||
RootItem* active_item = items_to_process.pop();
|
||||
|
||||
for (RootItem* child_item : active_item->childItems()) {
|
||||
if (!isItemChecked(child_item)) {
|
||||
if (!sourceModel()->isItemChecked(child_item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -259,12 +259,13 @@ void FeedsImportExportModel::importAsOPML20(const QByteArray& data, bool fetch_m
|
||||
emit layoutAboutToBeChanged();
|
||||
|
||||
setRootItem(root_item);
|
||||
|
||||
emit layoutChanged();
|
||||
emit parsingFinished(failed, succeded, false);
|
||||
}
|
||||
|
||||
bool FeedsImportExportModel::exportToTxtURLPerLine(QByteArray& result) {
|
||||
for (const Feed* const feed : m_rootItem->getSubTreeFeeds()) {
|
||||
for (const Feed* const feed : sourceModel()->rootItem()->getSubTreeFeeds()) {
|
||||
result += feed->url() + QL1S("\n");
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "services/abstract/accountcheckmodel.h"
|
||||
|
||||
class FeedsImportExportModel : public AccountCheckModel {
|
||||
class FeedsImportExportModel : public AccountCheckSortedModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -197,7 +197,7 @@ bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel* model,
|
||||
original_parents.push(target_root_node);
|
||||
QStack<RootItem*> new_parents;
|
||||
|
||||
new_parents.push(model->rootItem());
|
||||
new_parents.push(model->sourceModel()->rootItem());
|
||||
bool some_feed_category_error = false;
|
||||
|
||||
// Iterate all new items we would like to merge into current model.
|
||||
@ -206,7 +206,7 @@ bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel* model,
|
||||
RootItem* source_parent = new_parents.pop();
|
||||
|
||||
for (RootItem* source_item : source_parent->childItems()) {
|
||||
if (!model->isItemChecked(source_item)) {
|
||||
if (!model->sourceModel()->isItemChecked(source_item)) {
|
||||
// We can skip this item, because it is not checked and should not be imported.
|
||||
// NOTE: All descendants are thus skipped too.
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user