rssguard/src/librssguard/services/abstract/rootitem.h
2023-11-16 11:19:38 +01:00

293 lines
8.9 KiB
C++

// For license of this file, see <project-root-folder>/LICENSE.md.
#ifndef ROOTITEM_H
#define ROOTITEM_H
#include "core/message.h"
#include <QDateTime>
#include <QFont>
#include <QIcon>
class Category;
class Feed;
class Label;
class Search;
class ServiceRoot;
class QAction;
// Represents ROOT item of FeedsModel.
// NOTE: This class is derived to add functionality for
// all other non-root items of FeedsModel.
class RSSGUARD_DLLSPEC RootItem : public QObject {
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)
public:
enum class ReadStatus {
Unread = 0,
Read = 1,
Unknown = 256
};
// Holds statuses for messages
// to be switched importance (starred).
enum class Importance {
NotImportant = 0,
Important = 1,
Unknown = 256
};
// Describes the kind of the item.
enum class Kind {
Root = 1,
Bin = 2,
Feed = 4,
Category = 8,
ServiceRoot = 16,
Labels = 32,
Important = 64,
Label = 128,
Unread = 256,
Probes = 512,
Probe = 1024
};
// Constructors and destructors.
explicit RootItem(RootItem* parent_item = nullptr);
explicit RootItem(const RootItem& other);
virtual ~RootItem();
// Determines if this item should be kept always in the beginning of feeds list.
virtual QString hashCode() const;
virtual QString additionalTooltip() const;
// Returns list of specific actions which can be done with the item.
// Do not include general actions here like actions: Mark as read, Update, ...
// NOTE: Ownership of returned actions is not switched to caller, free them when needed.
virtual QList<QAction*> contextMenuFeedsList();
// Can properties of this item be edited?
virtual bool canBeEdited() const;
// Can the item be deleted?
virtual bool canBeDeleted() const;
// Performs deletion of the item, this
// method should NOT display any additional dialogs.
// Returns result status.
virtual bool deleteItem();
virtual bool isFetching() const;
// Performs all needed steps (DB update, remote server update)
// to mark this item as read/unread.
virtual bool markAsReadUnread(ReadStatus status);
// Get ALL undeleted messages from this item in one single list.
// This is currently used for displaying items in "newspaper mode".
virtual QList<Message> undeletedMessages() const;
// This method should "clean" all messages it contains.
//
// NOTE: What "clean" means? It means delete messages -> move them to recycle bin
// or eventually remove them completely if there is no recycle bin functionality.
//
// If this method is called on "recycle bin" instance of your
// service account, it should "empty" the recycle bin.
virtual bool cleanMessages(bool clear_only_read);
// Reloads current counts of articles in this item from DB and
// sets.
virtual void updateCounts(bool including_total_count);
virtual int row() const;
virtual QVariant data(int column, int role) const;
virtual Qt::ItemFlags additionalFlags() const;
virtual bool performDragDropChange(RootItem* target_item);
// Each item offers "counts" of messages.
// Returns counts of messages of all child items summed up.
virtual int countOfUnreadMessages() const;
virtual int countOfAllMessages() const;
RootItem* parent() const;
void setParent(RootItem* parent_item);
// Access to children.
RootItem* child(int row);
int childCount() const;
void appendChild(RootItem* child);
QList<RootItem*> childItems(RootItem::Kind kind) const;
QList<RootItem*> childItems() const;
QList<RootItem*>& childItems();
void clearChildren();
void setChildItems(const QList<RootItem*>& child_items);
// Removes particular child at given index.
// NOTE: Child is NOT freed from the memory.
bool removeChild(int index);
bool removeChild(RootItem* child);
// Checks whether "this" object is child (direct or indirect)
// of the given root.
bool isChildOf(const RootItem* root) const;
// Is "this" item parent (direct or indirect) if given child?
bool isParentOf(const RootItem* child) const;
// Returns flat list of all items from subtree where this item is a root.
// Returned list includes this item too.
QList<RootItem*> getSubTree() const;
QList<RootItem*> getSubTree(RootItem::Kind kind_of_item) const;
QList<Category*> getSubTreeCategories() const;
RootItem* getItemFromSubTree(std::function<bool(const RootItem*)> tester) const;
// Returns list of categories complemented by their own integer primary ID.
QHash<int, Category*> getSubTreeCategoriesForAssemble() const;
// Returns list of categories complemented by their own string CUSTOM ID.
QHash<QString, Category*> getHashedSubTreeCategories() const;
// Returns list of feeds complemented by their own string CUSTOM ID.
QHash<QString, Feed*> getHashedSubTreeFeeds() const;
QList<Feed*> getSubTreeFeeds(bool recursive = true) const;
QList<Feed*> getSubTreeAutoFetchingWithManualIntervalsFeeds() const;
QList<Feed*> getSubAutoFetchingEnabledFeeds() const;
// Returns the service root node which is direct or indirect parent of current item.
ServiceRoot* getParentServiceRoot() const;
RootItem::Kind kind() const;
void setKind(RootItem::Kind kind);
// Each item can have icon.
QIcon icon() const;
void setIcon(const QIcon& icon);
// Returns icon, even if item has "default" icon set, then
// this icon is extra loaded and returned.
QIcon fullIcon() const;
// This ALWAYS represents primary column number/ID under which
// the item is stored in DB.
int id() const;
// WARNING: Do not EVER call this method if your "this" object is derived
// from "ServiceRoot";
void setId(int id);
// Each item has its title.
QString title() const;
QString sanitizedTitle() const;
void setTitle(const QString& title);
// This should be in UTC and should be converted to localtime when needed.
QDateTime creationDate() const;
void setCreationDate(const QDateTime& creation_date);
QString description() const;
void setDescription(const QString& description);
// NOTE: For standard feed/category, this WILL equal to id().
QString customId() const;
int customNumericId() const;
void setCustomId(const QString& custom_id);
// Converters
Category* toCategory() const;
Feed* toFeed() const;
Label* toLabel() const;
Search* toProbe() const;
ServiceRoot* toServiceRoot() const;
bool keepOnTop() const;
void setKeepOnTop(bool keep_on_top);
// Sort order, when items in feeds list are sorted manually.
//
// NOTE: This is only used for "Account", "Category" and "Feed" classes
// which can be manually sorted. Other types like "Label" cannot be
// automatically sorted and are always sorted by title.
//
// Sort order number cannot be negative but order of list of items with same
// parent MUST form continuous series AND start with zero, for example:
// 0, 1, 2, 3, 4, ...
//
// NOTE: This is checked with DatabaseQueries::fixupOrders() method on app startup.
int sortOrder() const;
void setSortOrder(int sort_order);
private:
RootItem::Kind m_kind;
int m_id;
QString m_customId;
QString m_title;
QString m_description;
QIcon m_icon;
QDateTime m_creationDate;
bool m_keepOnTop;
int m_sortOrder;
QList<RootItem*> m_childItems;
RootItem* m_parentItem;
};
inline RootItem* RootItem::parent() const {
return m_parentItem;
}
inline void RootItem::setParent(RootItem* parent_item) {
m_parentItem = parent_item;
}
inline RootItem* RootItem::child(int row) {
return m_childItems.value(row);
}
inline int RootItem::childCount() const {
return m_childItems.size();
}
inline void RootItem::appendChild(RootItem* child) {
if (child != nullptr) {
m_childItems.append(child);
child->setParent(this);
}
}
inline QList<RootItem*> RootItem::childItems() const {
return m_childItems;
}
inline QList<RootItem*>& RootItem::childItems() {
return m_childItems;
}
inline void RootItem::clearChildren() {
m_childItems.clear();
}
inline void RootItem::setChildItems(const QList<RootItem*>& child_items) {
clearChildren();
for (RootItem* ch : child_items) {
appendChild(ch);
}
}
RootItem::Kind operator|(RootItem::Kind a, RootItem::Kind b);
RootItem::Kind operator&(RootItem::Kind a, RootItem::Kind b);
QDataStream& operator<<(QDataStream& out, const RootItem::Importance& myObj);
QDataStream& operator>>(QDataStream& in, RootItem::Importance& myObj);
QDataStream& operator<<(QDataStream& out, const RootItem::ReadStatus& myObj);
QDataStream& operator>>(QDataStream& in, RootItem::ReadStatus& myObj);
#endif // ROOTITEM_H