From 9c9030ab01d74167d7383c109efeea2f8456100b Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Fri, 20 Jan 2023 12:01:13 +0100 Subject: [PATCH] #809 for categories too --- .../services/abstract/rootitem.cpp | 57 ++++++++++++------- src/librssguard/services/abstract/rootitem.h | 6 +- .../services/abstract/serviceroot.cpp | 48 +++++++++++++--- .../services/abstract/serviceroot.h | 11 +++- 4 files changed, 92 insertions(+), 30 deletions(-) diff --git a/src/librssguard/services/abstract/rootitem.cpp b/src/librssguard/services/abstract/rootitem.cpp index 198b3f05e..52f6df9d7 100644 --- a/src/librssguard/services/abstract/rootitem.cpp +++ b/src/librssguard/services/abstract/rootitem.cpp @@ -14,9 +14,9 @@ #include RootItem::RootItem(RootItem* parent_item) - : QObject(nullptr), m_kind(RootItem::Kind::Root), m_id(NO_PARENT_CATEGORY), m_customId(QL1S("")), - m_title(QString()), m_description(QString()), m_creationDate(QDateTime::currentDateTimeUtc()), - m_keepOnTop(false), m_sortOrder(NO_PARENT_CATEGORY), m_childItems(QList()), m_parentItem(parent_item) {} + : QObject(nullptr), m_kind(RootItem::Kind::Root), m_id(NO_PARENT_CATEGORY), m_customId(QL1S("")), m_title(QString()), + m_description(QString()), m_creationDate(QDateTime::currentDateTimeUtc()), m_keepOnTop(false), + m_sortOrder(NO_PARENT_CATEGORY), m_childItems(QList()), m_parentItem(parent_item) {} RootItem::RootItem(const RootItem& other) : RootItem(nullptr) { setTitle(other.title()); @@ -28,7 +28,7 @@ RootItem::RootItem(const RootItem& other) : RootItem(nullptr) { // NOTE: We do not need to clone childs, because that would mean that // either source or target item tree would get corrupted. - //setChildItems(other.childItems()); + // setChildItems(other.childItems()); setParent(other.parent()); setCreationDate(other.creationDate()); @@ -43,10 +43,7 @@ QString RootItem::hashCode() const { ServiceRoot* root = getParentServiceRoot(); int acc_id = root == nullptr ? 0 : root->accountId(); - return - QString::number(acc_id) + QL1S("-") + - QString::number(int(kind())) + QL1S("-") + - QString::number(id()); + return QString::number(acc_id) + QL1S("-") + QString::number(int(kind())) + QL1S("-") + QString::number(id()); } QString RootItem::additionalTooltip() const { @@ -176,9 +173,11 @@ QVariant RootItem::data(int column, int role) const { else { int count_all = countOfAllMessages(); - return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString() - .replace(QSL(PLACEHOLDER_UNREAD_COUNTS), count_unread < 0 ? QSL("-") : QString::number(count_unread)) - .replace(QSL(PLACEHOLDER_ALL_COUNTS), count_all < 0 ? QSL("-") : QString::number(count_all)); + return qApp->settings() + ->value(GROUP(Feeds), SETTING(Feeds::CountFormat)) + .toString() + .replace(QSL(PLACEHOLDER_UNREAD_COUNTS), count_unread < 0 ? QSL("-") : QString::number(count_unread)) + .replace(QSL(PLACEHOLDER_ALL_COUNTS), count_all < 0 ? QSL("-") : QString::number(count_all)); } } else { @@ -217,21 +216,19 @@ bool RootItem::performDragDropChange(RootItem* target_item) { int RootItem::countOfUnreadMessages() const { return boolinq::from(m_childItems).sum([](RootItem* it) { - return (it->kind() == RootItem::Kind::Important || - it->kind() == RootItem::Kind::Unread || + return (it->kind() == RootItem::Kind::Important || it->kind() == RootItem::Kind::Unread || it->kind() == RootItem::Kind::Labels) - ? 0 - : it->countOfUnreadMessages(); + ? 0 + : it->countOfUnreadMessages(); }); } int RootItem::countOfAllMessages() const { return boolinq::from(m_childItems).sum([](RootItem* it) { - return (it->kind() == RootItem::Kind::Important || - it->kind() == RootItem::Kind::Unread || + return (it->kind() == RootItem::Kind::Important || it->kind() == RootItem::Kind::Unread || it->kind() == RootItem::Kind::Labels) - ? 0 - : it->countOfAllMessages(); + ? 0 + : it->countOfAllMessages(); }); } @@ -341,7 +338,7 @@ RootItem* RootItem::getItemFromSubTree(std::function test return nullptr; } -QHash RootItem::getHashedSubTreeCategories() const { +QHash RootItem::getSubTreeCategoriesForAssemble() const { QHash children; QList traversable_items; @@ -361,6 +358,26 @@ QHash RootItem::getHashedSubTreeCategories() const { return children; } +QHash RootItem::getHashedSubTreeCategories() const { + QHash children; + QList traversable_items; + + traversable_items.append(const_cast(this)); + + // Iterate all nested items. + while (!traversable_items.isEmpty()) { + RootItem* active_item = traversable_items.takeFirst(); + + if (active_item->kind() == RootItem::Kind::Category && !children.contains(active_item->customId())) { + children.insert(active_item->customId(), active_item->toCategory()); + } + + traversable_items.append(active_item->childItems()); + } + + return children; +} + QHash RootItem::getHashedSubTreeFeeds() const { QHash children; QList traversable_items; diff --git a/src/librssguard/services/abstract/rootitem.h b/src/librssguard/services/abstract/rootitem.h index fd4c56fcd..7085ae014 100644 --- a/src/librssguard/services/abstract/rootitem.h +++ b/src/librssguard/services/abstract/rootitem.h @@ -139,10 +139,14 @@ class RSSGUARD_DLLSPEC RootItem : public QObject { RootItem* getItemFromSubTree(std::function tester) const; // Returns list of categories complemented by their own integer primary ID. - QHash getHashedSubTreeCategories() const; + QHash getSubTreeCategoriesForAssemble() const; + + // Returns list of categories complemented by their own string CUSTOM ID. + QHash getHashedSubTreeCategories() const; // Returns list of feeds complemented by their own string CUSTOM ID. QHash getHashedSubTreeFeeds() const; + QList getSubTreeFeeds() const; QList getSubTreeAutoFetchingWithManualIntervalsFeeds() const; QList getSubAutoFetchingEnabledFeeds() const; diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 13b3f13c0..5a17ba89f 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -375,12 +375,10 @@ QMap ServiceRoot::storeCustomFeedsData() { feed_custom_data.insert(QSL("is_quiet"), feed->isQuiet()); feed_custom_data.insert(QSL("open_articles_directly"), feed->openArticlesDirectly()); - // NOTE: These is here specifically to be able to restore custom sort order. + // NOTE: This is here specifically to be able to restore custom sort order. // Otherwise the information is lost when list of feeds/folders is refreshed from remote // service. feed_custom_data.insert(QSL("sort_order"), feed->sortOrder()); - // feed_custom_data.insert(QSL("custom_id"), feed->customId()); - // feed_custom_data.insert(QSL("category"), feed->parent()->id()); custom_data.insert(feed->customId(), feed_custom_data); } @@ -388,6 +386,24 @@ QMap ServiceRoot::storeCustomFeedsData() { return custom_data; } +QMap ServiceRoot::storeCustomCategoriesData() { + QMap custom_data; + auto str = getSubTreeCategories(); + + for (const Category* cat : qAsConst(str)) { + QVariantMap cat_custom_data; + + // NOTE: This is here specifically to be able to restore custom sort order. + // Otherwise the information is lost when list of feeds/folders is refreshed from remote + // service. + cat_custom_data.insert(QSL("sort_order"), cat->sortOrder()); + + custom_data.insert(cat->customId(), cat_custom_data); + } + + return custom_data; +} + void ServiceRoot::restoreCustomFeedsData(const QMap& data, const QHash& feeds) { QMapIterator i(data); @@ -411,6 +427,12 @@ void ServiceRoot::restoreCustomFeedsData(const QMap& data, } } +void ServiceRoot::restoreCustomCategoriesData(const QMap& data, + const QHash& cats) { + Q_UNUSED(data) + Q_UNUSED(cats) +} + QNetworkProxy ServiceRoot::networkProxy() const { return m_networkProxy; } @@ -447,6 +469,7 @@ void ServiceRoot::syncIn() { qDebugNN << LOGSEC_CORE << "New feed tree for sync-in obtained."; auto feed_custom_data = storeCustomFeedsData(); + auto categories_custom_data = storeCustomCategoriesData(); // Remove from feeds model, then from SQL but leave messages intact. bool uses_remote_labels = @@ -457,9 +480,10 @@ void ServiceRoot::syncIn() { removeOldAccountFromDatabase(false, uses_remote_labels); // Re-sort items to accomodate current sort order. - resortAccountTree(new_tree, feed_custom_data); + resortAccountTree(new_tree, categories_custom_data, feed_custom_data); // Restore some local settings to feeds etc. + restoreCustomCategoriesData(categories_custom_data, new_tree->getHashedSubTreeCategories()); restoreCustomFeedsData(feed_custom_data, new_tree->getHashedSubTreeFeeds()); // Model is clean, now store new tree into DB and @@ -865,7 +889,7 @@ CacheForServiceRoot* ServiceRoot::toCache() const { } void ServiceRoot::assembleFeeds(const Assignment& feeds) { - QHash categories = getHashedSubTreeCategories(); + QHash categories = getSubTreeCategoriesForAssemble(); for (const AssignmentItem& feed : feeds) { if (feed.first == NO_PARENT_CATEGORY) { @@ -882,7 +906,9 @@ void ServiceRoot::assembleFeeds(const Assignment& feeds) { } } -void ServiceRoot::resortAccountTree(RootItem* tree, const QMap& custom_data) const { +void ServiceRoot::resortAccountTree(RootItem* tree, + const QMap& custom_category_data, + const QMap& custom_feed_data) const { // Iterate tree and rearrange children. QList traversable_items; @@ -896,8 +922,14 @@ void ServiceRoot::resortAccountTree(RootItem* tree, const QMapkind() == RootItem::Kind::Feed && rhs->kind() == RootItem::Kind::Feed) { - auto lhs_order = custom_data[lhs->customId()].value(QSL("sort_order")).toInt(); - auto rhs_order = custom_data[rhs->customId()].value(QSL("sort_order")).toInt(); + auto lhs_order = custom_feed_data[lhs->customId()].value(QSL("sort_order")).toInt(); + auto rhs_order = custom_feed_data[rhs->customId()].value(QSL("sort_order")).toInt(); + + return lhs_order < rhs_order; + } + else if (lhs->kind() == RootItem::Kind::Category && rhs->kind() == RootItem::Kind::Category) { + auto lhs_order = custom_category_data[lhs->customId()].value(QSL("sort_order")).toInt(); + auto rhs_order = custom_category_data[rhs->customId()].value(QSL("sort_order")).toInt(); return lhs_order < rhs_order; } diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index 6845b606e..e7a74f9e5 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -274,10 +274,19 @@ class ServiceRoot : public RootItem { void itemRemovalRequested(RootItem* item); private: - void resortAccountTree(RootItem* tree, const QMap& custom_data) const; + void resortAccountTree(RootItem* tree, + const QMap& custom_category_data, + const QMap& custom_feed_data) const; + // Key is feed's custom ID. virtual QMap storeCustomFeedsData(); + + // Key is category's custom ID. + virtual QMap storeCustomCategoriesData(); + virtual void restoreCustomFeedsData(const QMap& data, const QHash& feeds); + virtual void restoreCustomCategoriesData(const QMap& data, + const QHash& cats); protected: RecycleBin* m_recycleBin;