File indexing completed on 2024-05-05 09:27:17
0001 /* 0002 This file is part of Akregator. 0003 0004 SPDX-FileCopyrightText: 2004 Frank Osterfeld <osterfeld@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0007 */ 0008 0009 #pragma once 0010 0011 #include "akregator_export.h" 0012 #include <QList> 0013 #include <QObject> 0014 #include <QPoint> 0015 0016 class KJob; 0017 0018 class QDomDocument; 0019 class QDomElement; 0020 class QIcon; 0021 class QString; 0022 template<class T> 0023 class QList; 0024 0025 namespace Akregator 0026 { 0027 class ArticleListJob; 0028 class TreeNodeVisitor; 0029 class Article; 0030 class Feed; 0031 class Folder; 0032 class FetchQueue; 0033 0034 /** 0035 \brief Abstract base class for all kind of elements in the feed tree, like feeds and feed groups (and search folders later). 0036 0037 TODO: detailed description goes here 0038 */ 0039 class AKREGATOR_EXPORT TreeNode : public QObject 0040 { 0041 friend class ::Akregator::ArticleListJob; 0042 friend class ::Akregator::Folder; 0043 0044 Q_OBJECT 0045 0046 public: 0047 /** Standard constructor */ 0048 TreeNode(); 0049 0050 /** Standard destructor */ 0051 ~TreeNode() override; 0052 0053 virtual bool accept(TreeNodeVisitor *visitor) = 0; 0054 0055 /** The unread count, returns the number of new/unread articles in the node (for groups: the accumulated count of the subtree) 0056 @return number of new/unread articles */ 0057 0058 virtual int unread() const = 0; 0059 0060 /** returns the number of total articles in the node (for groups: the accumulated count of the subtree) 0061 @return number of articles */ 0062 0063 virtual int totalCount() const = 0; 0064 0065 /** Get title of node. 0066 @return the title of the node */ 0067 0068 [[nodiscard]] QString title() const; 0069 0070 /** Sets the title of the node. 0071 @c title should not contain entities. 0072 @param title the title string */ 0073 0074 void setTitle(const QString &title); 0075 0076 /** Get the next sibling. 0077 @return the next sibling, 0 if there is none */ 0078 0079 virtual const TreeNode *nextSibling() const; 0080 virtual TreeNode *nextSibling(); 0081 0082 /** Get the previous sibling. 0083 @return the previous sibling, 0 if there is none */ 0084 0085 virtual const TreeNode *prevSibling() const; 0086 virtual TreeNode *prevSibling(); 0087 0088 /** Returns the parent node. 0089 @return the parent feed group, 0 if there is none */ 0090 0091 virtual const Folder *parent() const; 0092 virtual Folder *parent(); 0093 0094 /** returns the (direct) children of this node. 0095 @return a list of pointers to the child nodes 0096 */ 0097 virtual QList<const TreeNode *> children() const; 0098 virtual QList<TreeNode *> children(); 0099 0100 virtual QList<const Feed *> feeds() const = 0; 0101 virtual QList<Feed *> feeds() = 0; 0102 0103 virtual QList<const Folder *> folders() const = 0; 0104 virtual QList<Folder *> folders() = 0; 0105 0106 virtual TreeNode *childAt(int pos); 0107 virtual const TreeNode *childAt(int pos) const; 0108 0109 /** Sets parent node; Don't call this directly, is done automatically by 0110 insertChild-methods in @ref Folder. */ 0111 0112 virtual void setParent(Folder *parent); 0113 0114 virtual QIcon icon() const = 0; 0115 0116 ArticleListJob *createListJob(); 0117 0118 /** Helps the rest of the app to decide if node should be handled as group or not. Only use where necessary, use polymorphism where possible. 0119 @return whether the node is a feed group or not */ 0120 0121 virtual bool isGroup() const = 0; 0122 0123 /** returns if the node represents an aggregation, i.e. containing 0124 * items from more than once source feed. Folders and virtual folders 0125 * are aggregations, feeds are not. 0126 */ 0127 virtual bool isAggregation() const = 0; 0128 0129 /** exports node and child nodes to OPML (with akregator settings) 0130 @param parent the dom element the child node will be attached to 0131 @param document the opml document */ 0132 0133 virtual QDomElement toOPML(QDomElement parent, QDomDocument document) const = 0; 0134 0135 /** 0136 @param doNotify notification on changes on/off flag 0137 */ 0138 0139 virtual void setNotificationMode(bool doNotify); 0140 0141 /** returns the next node in the tree. 0142 Calling next() unless it returns 0 iterates through the tree in pre-order 0143 */ 0144 virtual const TreeNode *next() const = 0; 0145 virtual TreeNode *next() = 0; 0146 0147 /** returns the ID of this node. IDs are managed by FeedList objects and must be unique within the list. Some IDs have a special meaning: 0148 @c 0 is the default value and indicates that no ID was set 0149 @c 1 is reserved for the "All Feeds" root node */ 0150 virtual uint id() const; 0151 0152 /** sets the ID */ 0153 virtual void setId(uint id); 0154 0155 QPoint listViewScrollBarPositions() const; 0156 void setListViewScrollBarPositions(const QPoint &pos); 0157 0158 virtual KJob *createMarkAsReadJob() = 0; 0159 0160 public Q_SLOTS: 0161 0162 /** adds node to a fetch queue 0163 @param queue pointer to the queue 0164 @param intervalFetchesOnly determines whether to allow only interval fetches 0165 */ 0166 virtual void slotAddToFetchQueue(Akregator::FetchQueue *queue, bool intervalFetchesOnly = false) = 0; 0167 0168 Q_SIGNALS: 0169 0170 /** Emitted when this object is deleted. */ 0171 void signalDestroyed(Akregator::TreeNode *); 0172 0173 /** Notification mechanism: emitted, when the node was modified and notification is enabled. A node change is renamed title, icon, unread count. Added, 0174 * updated or removed articles are not notified via this signal */ 0175 void signalChanged(Akregator::TreeNode *); 0176 0177 /** emitted when new articles were added to this node or any node in the subtree (for folders). Note that this has nothing to do with fetching, the article 0178 might have been moved from somewhere else in the tree into this subtree, e.g. by moving the feed the article is in. 0179 @param TreeNode* the node articles were added to 0180 @param guids the guids of the articles added 0181 */ 0182 void signalArticlesAdded(Akregator::TreeNode *, const QList<Akregator::Article> &guids); 0183 0184 /** emitted when articles were updated */ 0185 void signalArticlesUpdated(Akregator::TreeNode *, const QList<Akregator::Article> &guids); 0186 0187 /** emitted when articles were removed from this subtree. Note that this has nothing to do with actual article deletion! The article might have moved 0188 * somewhere else in the tree, e.g. if the user moved the feed */ 0189 void signalArticlesRemoved(Akregator::TreeNode *, const QList<Akregator::Article> &guids); 0190 0191 protected: 0192 /** call this if you modified the actual node (title, unread count). 0193 Call this only when the _actual_ _node_ has changed, i.e. title, unread count. Don't use for article changes! 0194 Will do notification immediately or cache it, depending on @c m_doNotify. */ 0195 virtual void nodeModified(); 0196 0197 /** call this if the articles in the node were changed. Sends signalArticlesAdded/Updated/Removed signals 0198 Will do notification immediately or cache it, depending on @c m_doNotify. */ 0199 virtual void articlesModified(); 0200 0201 /** reimplement this in subclasses to do the actual notification 0202 called by articlesModified 0203 */ 0204 virtual void doArticleNotification(); 0205 0206 void emitSignalDestroyed(); 0207 0208 private: 0209 /** Returns a sequence of the articles this node contains. For feed groups, this returns a concatenated list of all articles in the sub tree. 0210 @return sequence of articles */ 0211 0212 virtual QList<Article> articles() = 0; 0213 0214 private: 0215 bool m_doNotify = true; 0216 bool m_nodeChangeOccurred = false; 0217 bool m_articleChangeOccurred = false; 0218 QString m_title; 0219 Folder *m_parent = nullptr; 0220 QPoint m_scrollBarPositions; 0221 uint m_id = 0; 0222 bool m_signalDestroyedEmitted = false; 0223 }; 0224 } // namespace Akregator