File indexing completed on 2024-05-05 05:13:01
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 0013 #include "feedlistmanagementinterface.h" 0014 0015 #include <QObject> 0016 0017 #include <QSharedPointer> 0018 0019 #include <memory> 0020 0021 class QDomDocument; 0022 class QDomNode; 0023 template<class T> 0024 class QList; 0025 template<class K, class T> 0026 class QHash; 0027 class QString; 0028 0029 class KJob; 0030 0031 namespace Akregator 0032 { 0033 class Article; 0034 class Feed; 0035 class FeedList; 0036 class FetchQueue; 0037 class Folder; 0038 class TreeNode; 0039 0040 namespace Backend 0041 { 0042 class Storage; 0043 } 0044 0045 class AKREGATOR_EXPORT FeedListManagementImpl : public FeedListManagementInterface 0046 { 0047 public: 0048 explicit FeedListManagementImpl(const QSharedPointer<FeedList> &list = QSharedPointer<FeedList>()); 0049 void setFeedList(const QSharedPointer<FeedList> &list); 0050 0051 [[nodiscard]] QStringList categories() const override; 0052 [[nodiscard]] QStringList feeds(const QString &catId) const override; 0053 void addFeed(const QString &url, const QString &catId) override; 0054 void removeFeed(const QString &url, const QString &catId) override; 0055 [[nodiscard]] QString getCategoryName(const QString &catId) const override; 0056 0057 private: 0058 QSharedPointer<FeedList> m_feedList; 0059 }; 0060 0061 class FeedListPrivate; 0062 0063 /** @class FeedList 0064 The model of a feed tree, represents an OPML document. Contains an additional root node "All Feeds" which isn't stored. Note that a node instance must not 0065 be in more than one FeedList at a time! When deleting the feed list, all contained nodes are deleted! */ 0066 0067 class AKREGATOR_EXPORT FeedList : public QObject 0068 { 0069 Q_OBJECT 0070 public: 0071 explicit FeedList(Akregator::Backend::Storage *storage); 0072 0073 /** Destructor. Contained nodes are deleted! */ 0074 ~FeedList() override; 0075 0076 const Folder *allFeedsFolder() const; 0077 Folder *allFeedsFolder(); 0078 0079 [[nodiscard]] bool isEmpty() const; 0080 0081 const TreeNode *findByID(uint id) const; 0082 TreeNode *findByID(uint id); 0083 0084 [[nodiscard]] QList<const TreeNode *> findByTitle(const QString &title) const; 0085 [[nodiscard]] QList<TreeNode *> findByTitle(const QString &title); 0086 0087 /** returns the title of the feed list (as used in the OPML document) */ 0088 [[nodiscard]] QString title() const; 0089 0090 /** sets the title of the feed list */ 0091 void setTitle(const QString &name); 0092 0093 /** 0094 * returns all feeds in this list 0095 */ 0096 [[nodiscard]] QList<const Akregator::Feed *> feeds() const; 0097 [[nodiscard]] QList<Akregator::Feed *> feeds(); 0098 0099 [[nodiscard]] QList<uint> feedIds() const; 0100 0101 /** 0102 * returns all folders in this list 0103 */ 0104 [[nodiscard]] QList<const Folder *> folders() const; 0105 [[nodiscard]] QList<Folder *> folders(); 0106 0107 /** appends another feed list as sub tree. The root node of @c list is ignored. NOTE: nodes are _moved_ from @c list to this feed list, not copied */ 0108 0109 void append(FeedList *list, Folder *parent = nullptr, TreeNode *after = nullptr); 0110 0111 /** reads an OPML document and appends the items to this list 0112 @param doc the OPML document to parse 0113 @return whether parsing was successful or not (TODO: make errors more detailed) 0114 */ 0115 [[nodiscard]] bool readFromOpml(const QDomDocument &doc); 0116 0117 /** exports the feed list as OPML. The root node ("All Feeds") is ignored! */ 0118 [[nodiscard]] QDomDocument toOpml() const; 0119 0120 /** returns a feed object for a given feed URL. If the feed list does not contain a feed with @c url, NULL is returned. If it contains the same feed 0121 * multiple times, any of the Feed objects is returned. */ 0122 const Feed *findByURL(const QString &feedURL) const; 0123 Feed *findByURL(const QString &feedURL); 0124 0125 const Article findArticle(const QString &feedURL, const QString &guid) const; 0126 0127 [[nodiscard]] int unread() const; 0128 0129 void addToFetchQueue(FetchQueue *queue, bool intervalOnly = false); 0130 KJob *createMarkAsReadJob(); 0131 0132 Q_SIGNALS: 0133 0134 void signalDestroyed(Akregator::FeedList *); 0135 0136 /** emitted when a node was added to the list */ 0137 void signalNodeAdded(Akregator::TreeNode *); 0138 0139 /** emitted when a node was removed from the list */ 0140 void signalNodeRemoved(Akregator::TreeNode *); 0141 0142 void signalAboutToRemoveNode(Akregator::TreeNode *); 0143 0144 void signalNodeChanged(Akregator::TreeNode *); 0145 0146 /** emitted when fetching started */ 0147 void fetchStarted(Akregator::Feed *); 0148 0149 /** emitted when feed finished fetching */ 0150 void fetched(Akregator::Feed *); 0151 0152 /** emitted when a fetch error occurred */ 0153 void fetchError(Akregator::Feed *); 0154 /** emitted when a feed URL was found by auto discovery */ 0155 void fetchDiscovery(Akregator::Feed *); 0156 0157 /** emitted when a fetch is aborted */ 0158 void fetchAborted(Akregator::Feed *); 0159 0160 void unreadCountChanged(int unread); 0161 0162 private: 0163 void addNode(TreeNode *node, bool preserveID); 0164 void removeNode(TreeNode *node); 0165 0166 uint generateID() const; 0167 void setRootNode(Folder *folder); 0168 0169 void parseChildNodes(QDomNode &node, Folder *parent); 0170 0171 private Q_SLOTS: 0172 0173 void slotNodeDestroyed(Akregator::TreeNode *node); 0174 void slotNodeAdded(Akregator::TreeNode *node); 0175 void slotNodeRemoved(Akregator::Folder *parent, Akregator::TreeNode *node); 0176 void rootNodeChanged(); 0177 0178 private: 0179 friend class AddNodeVisitor; 0180 class AddNodeVisitor; 0181 0182 friend class RemoveNodeVisitor; 0183 class RemoveNodeVisitor; 0184 0185 friend class FeedListPrivate; 0186 std::unique_ptr<FeedListPrivate> const d; 0187 }; 0188 } // namespace Akregator