1 /* 2 This file is part of Akregator. 3 4 SPDX-FileCopyrightText: 2004 Frank Osterfeld <osterfeld@kde.org> 5 6 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 7 */ 8 9 #pragma once 10 11 #include "akregator_export.h" 12 #include <QObject> 13 #include <QPoint> 14 #include <QVector> 15 16 class KJob; 17 18 class QDomDocument; 19 class QDomElement; 20 class QIcon; 21 class QString; 22 template<class T> class QList; 23 24 namespace Akregator 25 { 26 class ArticleListJob; 27 class TreeNodeVisitor; 28 class Article; 29 class Feed; 30 class Folder; 31 class FetchQueue; 32 33 /** 34 \brief Abstract base class for all kind of elements in the feed tree, like feeds and feed groups (and search folders later). 35 36 TODO: detailed description goes here 37 */ 38 class AKREGATOR_EXPORT TreeNode : public QObject 39 { 40 friend class ::Akregator::ArticleListJob; 41 friend class ::Akregator::Folder; 42 43 Q_OBJECT 44 45 public: 46 /** Standard constructor */ 47 TreeNode(); 48 49 /** Standard destructor */ 50 ~TreeNode() override; 51 52 virtual bool accept(TreeNodeVisitor *visitor) = 0; 53 54 /** The unread count, returns the number of new/unread articles in the node (for groups: the accumulated count of the subtree) 55 @return number of new/unread articles */ 56 57 virtual int unread() const = 0; 58 59 /** returns the number of total articles in the node (for groups: the accumulated count of the subtree) 60 @return number of articles */ 61 62 virtual int totalCount() const = 0; 63 64 /** Get title of node. 65 @return the title of the node */ 66 67 Q_REQUIRED_RESULT QString title() const; 68 69 /** Sets the title of the node. 70 @c title should not contain entities. 71 @param title the title string */ 72 73 void setTitle(const QString &title); 74 75 /** Get the next sibling. 76 @return the next sibling, 0 if there is none */ 77 78 virtual const TreeNode *nextSibling() const; 79 virtual TreeNode *nextSibling(); 80 81 /** Get the previous sibling. 82 @return the previous sibling, 0 if there is none */ 83 84 virtual const TreeNode *prevSibling() const; 85 virtual TreeNode *prevSibling(); 86 87 /** Returns the parent node. 88 @return the parent feed group, 0 if there is none */ 89 90 virtual const Folder *parent() const; 91 virtual Folder *parent(); 92 93 /** returns the (direct) children of this node. 94 @return a list of pointers to the child nodes 95 */ 96 virtual QList<const TreeNode *> children() const; 97 virtual QList<TreeNode *> children(); 98 99 virtual QVector<const Feed *> feeds() const = 0; 100 virtual QVector<Feed *> feeds() = 0; 101 102 virtual QVector<const Folder *> folders() const = 0; 103 virtual QVector<Folder *> folders() = 0; 104 105 virtual TreeNode *childAt(int pos); 106 virtual const TreeNode *childAt(int pos) const; 107 108 /** Sets parent node; Don't call this directly, is done automatically by 109 insertChild-methods in @ref Folder. */ 110 111 virtual void setParent(Folder *parent); 112 113 virtual QIcon icon() const = 0; 114 115 ArticleListJob *createListJob(); 116 117 /** 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. 118 @return whether the node is a feed group or not */ 119 120 virtual bool isGroup() const = 0; 121 122 /** returns if the node represents an aggregation, i.e. containing 123 * items from more than once source feed. Folders and virtual folders 124 * are aggregations, feeds are not. 125 */ 126 virtual bool isAggregation() const = 0; 127 128 /** exports node and child nodes to OPML (with akregator settings) 129 @param parent the dom element the child node will be attached to 130 @param document the opml document */ 131 132 virtual QDomElement toOPML(QDomElement parent, QDomDocument document) const = 0; 133 134 /** 135 @param doNotify notification on changes on/off flag 136 */ 137 138 virtual void setNotificationMode(bool doNotify); 139 140 /** returns the next node in the tree. 141 Calling next() unless it returns 0 iterates through the tree in pre-order 142 */ 143 virtual const TreeNode *next() const = 0; 144 virtual TreeNode *next() = 0; 145 146 /** 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: 147 @c 0 is the default value and indicates that no ID was set 148 @c 1 is reserved for the "All Feeds" root node */ 149 virtual uint id() const; 150 151 /** sets the ID */ 152 virtual void setId(uint id); 153 154 QPoint listViewScrollBarPositions() const; 155 void setListViewScrollBarPositions(const QPoint &pos); 156 157 virtual KJob *createMarkAsReadJob() = 0; 158 159 public Q_SLOTS: 160 161 /** adds node to a fetch queue 162 @param queue pointer to the queue 163 @param intervalFetchesOnly determines whether to allow only interval fetches 164 */ 165 virtual void slotAddToFetchQueue(Akregator::FetchQueue *queue, bool intervalFetchesOnly = false) = 0; 166 167 Q_SIGNALS: 168 169 /** Emitted when this object is deleted. */ 170 void signalDestroyed(Akregator::TreeNode *); 171 172 /** Notification mechanism: emitted, when the node was modified and notification is enabled. A node change is renamed title, icon, unread count. Added, 173 * updated or removed articles are not notified via this signal */ 174 void signalChanged(Akregator::TreeNode *); 175 176 /** 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 177 might have been moved from somewhere else in the tree into this subtree, e.g. by moving the feed the article is in. 178 @param TreeNode* the node articles were added to 179 @param guids the guids of the articles added 180 */ 181 void signalArticlesAdded(Akregator::TreeNode *, const QVector<Akregator::Article> &guids); 182 183 /** emitted when articles were updated */ 184 void signalArticlesUpdated(Akregator::TreeNode *, const QVector<Akregator::Article> &guids); 185 186 /** emitted when articles were removed from this subtree. Note that this has nothing to do with actual article deletion! The article might have moved 187 * somewhere else in the tree, e.g. if the user moved the feed */ 188 void signalArticlesRemoved(Akregator::TreeNode *, const QVector<Akregator::Article> &guids); 189 190 protected: 191 /** call this if you modified the actual node (title, unread count). 192 Call this only when the _actual_ _node_ has changed, i.e. title, unread count. Don't use for article changes! 193 Will do notification immediately or cache it, depending on @c m_doNotify. */ 194 virtual void nodeModified(); 195 196 /** call this if the articles in the node were changed. Sends signalArticlesAdded/Updated/Removed signals 197 Will do notification immediately or cache it, depending on @c m_doNotify. */ 198 virtual void articlesModified(); 199 200 /** reimplement this in subclasses to do the actual notification 201 called by articlesModified 202 */ 203 virtual void doArticleNotification(); 204 205 void emitSignalDestroyed(); 206 207 private: 208 /** Returns a sequence of the articles this node contains. For feed groups, this returns a concatenated list of all articles in the sub tree. 209 @return sequence of articles */ 210 211 virtual QVector<Article> articles() = 0; 212 213 private: 214 bool m_doNotify = true; 215 bool m_nodeChangeOccurred = false; 216 bool m_articleChangeOccurred = false; 217 QString m_title; 218 Folder *m_parent = nullptr; 219 QPoint m_scrollBarPositions; 220 uint m_id = 0; 221 bool m_signalDestroyedEmitted = false; 222 }; 223 } // namespace Akregator 224 225