1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 **************************************************************************/
19 
20 #ifndef OTTER_FEEDSMODEL_H
21 #define OTTER_FEEDSMODEL_H
22 
23 #include <QtCore/QUrl>
24 #include <QtCore/QXmlStreamReader>
25 #include <QtCore/QXmlStreamWriter>
26 #include <QtGui/QStandardItemModel>
27 
28 namespace Otter
29 {
30 
31 class Feed;
32 
33 class FeedsModel final : public QStandardItemModel
34 {
35 	Q_OBJECT
36 
37 public:
38 	enum EntryType
39 	{
40 		UnknownEntry = 0,
41 		RootEntry,
42 		TrashEntry,
43 		FolderEntry,
44 		FeedEntry,
45 		CategoryEntry
46 	};
47 
48 	enum EntryRole
49 	{
50 		TitleRole = Qt::DisplayRole,
51 		UrlRole = Qt::StatusTipRole,
52 		DescriptionRole = Qt::ToolTipRole,
53 		IdentifierRole = Qt::UserRole,
54 		TypeRole,
55 		LastUpdateTimeRole,
56 		LastSynchronizationTimeRole,
57 		UpdateIntervalRole,
58 		IsTrashedRole,
59 		IsUpdatingRole,
60 		HasErrorsRole,
61 		UserRole
62 	};
63 
64 	class Entry final : public QStandardItem
65 	{
66 	public:
67 		Feed* getFeed() const;
68 		QVariant data(int role) const override;
69 		QVariant getRawData(int role) const;
70 		QVector<Feed*> getFeeds() const;
71 		EntryType getType() const;
72 		bool isAncestorOf(Entry *child) const;
73 		bool operator<(const QStandardItem &other) const override;
74 
75 	protected:
76 		explicit Entry(Feed *feed = nullptr);
77 
78 	private:
79 		Feed *m_feed;
80 
81 	friend class FeedsModel;
82 	};
83 
84 	explicit FeedsModel(const QString &path, QObject *parent = nullptr);
85 
86 	void beginImport(Entry *target, int estimatedUrlsAmount);
87 	void endImport();
88 	void trashEntry(Entry *entry);
89 	void restoreEntry(Entry *entry);
90 	void removeEntry(Entry *entry);
91 	Entry* addEntry(EntryType type, const QMap<int, QVariant> &metaData = {}, Entry *parent = nullptr, int index = -1);
92 	Entry* addEntry(Feed *feed, Entry *parent = nullptr, int index = -1);
93 	Entry* getEntry(const QModelIndex &index) const;
94 	Entry* getEntry(quint64 identifier) const;
95 	Entry* getRootEntry() const;
96 	Entry* getTrashEntry() const;
97 	QMimeData* mimeData(const QModelIndexList &indexes) const override;
98 	QStringList mimeTypes() const override;
99 	QVector<Entry*> getEntries(const QUrl &url) const;
100 	bool moveEntry(Entry *entry, Entry *newParent, int newRow = -1);
101 	bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
102 	bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
103 	bool save(const QString &path) const;
104 	bool setData(const QModelIndex &index, const QVariant &value, int role) override;
105 	bool hasFeed(const QUrl &url) const;
106 
107 public slots:
108 	void emptyTrash();
109 
110 protected:
111 	void readEntry(QXmlStreamReader *reader, Entry *parent);
112 	void writeEntry(QXmlStreamWriter *writer, Entry *entry) const;
113 	void removeEntryUrl(Entry *entry);
114 	void readdEntryUrl(Entry *entry);
115 	void createIdentifier(Entry *entry);
116 	void handleUrlChanged(Entry *entry, const QUrl &newUrl, const QUrl &oldUrl = {});
117 
118 private:
119 	Entry *m_rootEntry;
120 	Entry *m_trashEntry;
121 	Entry *m_importTargetEntry;
122 	QHash<Entry*, QPair<QModelIndex, int> > m_trash;
123 	QHash<QUrl, QVector<Entry*> > m_urls;
124 	QMap<quint64, Entry*> m_identifiers;
125 
126 signals:
127 	void entryAdded(Entry *entry);
128 	void entryModified(Entry *entry);
129 	void entryMoved(Entry *entry, Entry *previousParent, int previousRow);
130 	void entryTrashed(Entry *entry, Entry *previousParent);
131 	void entryRestored(Entry *entry);
132 	void entryRemoved(Entry *entry, Entry *previousParent);
133 	void modelModified();
134 };
135 
136 }
137 
138 #endif
139