File indexing completed on 2024-04-28 05:11:03

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