This commit is contained in:
Martin Rotter 2022-10-14 13:59:06 +02:00
parent 49785b348a
commit edb8ec5866
3 changed files with 62 additions and 35 deletions

View file

@ -19,25 +19,19 @@ class QAction;
// NOTE: This class is derived to add functionality for
// all other non-root items of FeedsModel.
class RSSGUARD_DLLSPEC RootItem : public QObject {
Q_OBJECT
Q_OBJECT
// Added for message filtering with labels.
Q_PROPERTY(QString title READ title)
Q_PROPERTY(int id READ id)
Q_PROPERTY(QString customId READ customId)
// Added for message filtering with labels.
Q_PROPERTY(QString title READ title)
Q_PROPERTY(int id READ id)
Q_PROPERTY(QString customId READ customId)
public:
enum class ReadStatus {
Unread = 0,
Read = 1
};
enum class ReadStatus { Unread = 0, Read = 1 };
// Holds statuses for messages
// to be switched importance (starred).
enum class Importance {
NotImportant = 0,
Important = 1
};
enum class Importance { NotImportant = 0, Important = 1 };
// Describes the kind of the item.
enum class Kind {
@ -119,6 +113,8 @@ class RSSGUARD_DLLSPEC RootItem : public QObject {
int childCount() const;
void appendChild(RootItem* child);
QList<RootItem*> childItems() const;
QList<RootItem*>& childItems();
void clearChildren();
void setChildItems(const QList<RootItem*>& child_items);
@ -254,6 +250,10 @@ inline QList<RootItem*> RootItem::childItems() const {
return m_childItems;
}
inline QList<RootItem*>& RootItem::childItems() {
return m_childItems;
}
inline void RootItem::clearChildren() {
m_childItems.clear();
}

View file

@ -260,17 +260,6 @@ bool ServiceRoot::cleanFeeds(const QList<Feed*>& items, bool clean_read_only) {
}
}
void ServiceRoot::storeNewFeedTree(RootItem* root) {
try {
DatabaseQueries::storeAccountTree(qApp->database()->driver()->connection(metaObject()->className()),
root,
accountId());
}
catch (const ApplicationException& ex) {
qFatal("Cannot store account tree: '%s'.", qPrintable(ex.message()));
}
}
void ServiceRoot::removeLeftOverMessages() {
QSqlDatabase database = qApp->database()->driver()->connection(metaObject()->className());
@ -379,13 +368,21 @@ QMap<QString, QVariantMap> ServiceRoot::storeCustomFeedsData() {
QVariantMap feed_custom_data;
// TODO: This could potentially call Feed::customDatabaseData() and append it
// to this map and also subsequently restore.
// to this map and also subsequently restore, but the method is at this point
// not really used by any syncable plugin.
feed_custom_data.insert(QSL("auto_update_interval"), feed->autoUpdateInterval());
feed_custom_data.insert(QSL("auto_update_type"), int(feed->autoUpdateType()));
feed_custom_data.insert(QSL("msg_filters"), QVariant::fromValue(feed->messageFilters()));
feed_custom_data.insert(QSL("is_off"), feed->isSwitchedOff());
feed_custom_data.insert(QSL("open_articles_directly"), feed->openArticlesDirectly());
// NOTE: These are 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);
}
@ -459,12 +456,17 @@ void ServiceRoot::syncIn() {
cleanAllItemsFromModel(uses_remote_labels);
removeOldAccountFromDatabase(false, uses_remote_labels);
// Re-sort items to accomodate current sort order.
resortAccountTree(new_tree, feed_custom_data);
// Restore some local settings to feeds etc.
restoreCustomFeedsData(feed_custom_data, new_tree->getHashedSubTreeFeeds());
// Model is clean, now store new tree into DB and
// set primary IDs of the items.
storeNewFeedTree(new_tree);
DatabaseQueries::storeAccountTree(qApp->database()->driver()->connection(metaObject()->className()),
new_tree,
accountId());
// We have new feed, some feeds were maybe removed,
// so remove left over messages and filter assignments.
@ -880,6 +882,34 @@ void ServiceRoot::assembleFeeds(const Assignment& feeds) {
}
}
void ServiceRoot::resortAccountTree(RootItem* tree, const QMap<QString, QVariantMap>& custom_data) const {
// Iterate tree and rearrange children.
QList<RootItem*> traversable_items;
traversable_items.append(tree);
while (!traversable_items.isEmpty()) {
auto* root = traversable_items.takeFirst();
auto& chldr = root->childItems();
// Sort children so that we are sure that feeds are sorted with sort order
// other item types do not matter.
std::sort(chldr.begin(), chldr.end(), [&](const RootItem* lhs, const RootItem* rhs) {
if (lhs->kind() == 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();
return lhs_order < rhs_order;
}
else {
return lhs->kind() < rhs->kind();
}
});
traversable_items.append(root->childItems());
}
}
void ServiceRoot::assembleCategories(const Assignment& categories) {
Assignment editable_categories = categories;
QHash<int, RootItem*> assignments;

View file

@ -28,7 +28,7 @@ class CacheForServiceRoot;
// NOTE: The root usually contains some core functionality of the
// service like service account username/password etc.
class ServiceRoot : public RootItem {
Q_OBJECT
Q_OBJECT
public:
enum class LabelOperation {
@ -41,11 +41,7 @@ class ServiceRoot : public RootItem {
Synchronised = 8
};
enum class BagOfMessages {
Read,
Unread,
Starred
};
enum class BagOfMessages { Read, Unread, Starred };
public:
explicit ServiceRoot(RootItem* parent = nullptr);
@ -70,7 +66,8 @@ class ServiceRoot : public RootItem {
virtual void setCustomDatabaseData(const QVariantHash& data);
virtual bool wantsBaggedIdsOfExistingMessages() const;
virtual void aboutToBeginFeedFetching(const QList<Feed*>& feeds,
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>& stated_messages,
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>&
stated_messages,
const QHash<QString, QStringList>& tagged_messages);
// Returns list of specific actions for "Add new item" main window menu.
@ -233,14 +230,12 @@ class ServiceRoot : public RootItem {
virtual void syncIn();
protected:
// This method should obtain new tree of feed/categories/whatever to perform sync in.
virtual RootItem* obtainNewTreeForSyncIn() const;
// Removes all messages/categories/feeds which are
// associated with this account.
void removeOldAccountFromDatabase(bool delete_messages_too, bool delete_labels_too);
void storeNewFeedTree(RootItem* root);
void cleanAllItemsFromModel(bool clean_labels_too);
void appendCommonNodes();
@ -278,6 +273,8 @@ class ServiceRoot : public RootItem {
void itemRemovalRequested(RootItem* item);
private:
void resortAccountTree(RootItem* tree, const QMap<QString, QVariantMap>& custom_data) const;
virtual QMap<QString, QVariantMap> storeCustomFeedsData();
virtual void restoreCustomFeedsData(const QMap<QString, QVariantMap>& data, const QHash<QString, Feed*>& feeds);