1
0
mirror of https://github.com/d47081/qBittorrent.git synced 2025-01-23 13:04:23 +00:00

Redesign RSS base classes.

This commit is contained in:
Vladimir Golovnev (Glassez) 2015-10-17 18:59:04 +03:00 committed by Vladimir Golovnev (qlassez)
parent 6f7ae728eb
commit 28ed981082
16 changed files with 232 additions and 266 deletions

View File

@ -43,7 +43,7 @@ HEADERS += \
$$PWD/rss/rssarticle.h \ $$PWD/rss/rssarticle.h \
$$PWD/rss/rssdownloadrule.h \ $$PWD/rss/rssdownloadrule.h \
$$PWD/rss/rssdownloadrulelist.h \ $$PWD/rss/rssdownloadrulelist.h \
$$PWD/rss/rssparser.h \ $$PWD/rss/private/rssparser.h \
$$PWD/utils/fs.h \ $$PWD/utils/fs.h \
$$PWD/utils/gzip.h \ $$PWD/utils/gzip.h \
$$PWD/utils/misc.h \ $$PWD/utils/misc.h \
@ -94,7 +94,7 @@ SOURCES += \
$$PWD/rss/rssdownloadrule.cpp \ $$PWD/rss/rssdownloadrule.cpp \
$$PWD/rss/rssdownloadrulelist.cpp \ $$PWD/rss/rssdownloadrulelist.cpp \
$$PWD/rss/rssfile.cpp \ $$PWD/rss/rssfile.cpp \
$$PWD/rss/rssparser.cpp \ $$PWD/rss/private/rssparser.cpp \
$$PWD/utils/fs.cpp \ $$PWD/utils/fs.cpp \
$$PWD/utils/gzip.cpp \ $$PWD/utils/gzip.cpp \
$$PWD/utils/misc.cpp \ $$PWD/utils/misc.cpp \

View File

@ -29,22 +29,27 @@
*/ */
#include <QDebug> #include <QDebug>
#include <QDateTime>
#include <QFile> #include <QFile>
#include <QRegExp> #include <QRegExp>
#include <QStringList> #include <QStringList>
#include <QVariant> #include <QVariant>
#include <QXmlStreamReader>
#include "base/utils/fs.h" #include "base/utils/fs.h"
#include "rssparser.h" #include "rssparser.h"
namespace Rss namespace Rss
{
namespace Private
{ {
struct ParsingJob struct ParsingJob
{ {
QString feedUrl; QString feedUrl;
QString filePath; QByteArray feedData;
}; };
} }
}
static const char shortDay[][4] = { static const char shortDay[][4] = {
"Mon", "Tue", "Wed", "Mon", "Tue", "Wed",
@ -64,7 +69,7 @@ static const char shortMonth[][4] = {
"Sep", "Oct", "Nov", "Dec" "Sep", "Oct", "Nov", "Dec"
}; };
using namespace Rss; using namespace Rss::Private;
Parser::Parser(QObject *parent) Parser::Parser(QObject *parent)
: QThread(parent) : QThread(parent)
@ -227,11 +232,11 @@ QDateTime Parser::parseDate(const QString &string)
return result; return result;
} }
void Parser::parseRssFile(const QString &feedUrl, const QString &filePath) void Parser::parseFeedData(const QString &feedUrl, const QByteArray &feedData)
{ {
qDebug() << Q_FUNC_INFO << feedUrl << filePath; qDebug() << Q_FUNC_INFO << feedUrl;
m_mutex.lock(); m_mutex.lock();
ParsingJob job = { feedUrl, Utils::Fs::fromNativePath(filePath) }; ParsingJob job = { feedUrl, feedData };
m_queue.enqueue(job); m_queue.enqueue(job);
// Wake up thread. // Wake up thread.
if (m_queue.count() == 1) { if (m_queue.count() == 1) {
@ -487,14 +492,9 @@ void Parser::parseAtomChannel(QXmlStreamReader &xml, const QString &feedUrl)
// read and create items from a rss document // read and create items from a rss document
void Parser::parseFeed(const ParsingJob &job) void Parser::parseFeed(const ParsingJob &job)
{ {
qDebug() << Q_FUNC_INFO << job.feedUrl << job.filePath; qDebug() << Q_FUNC_INFO << job.feedUrl;
QFile fileRss(job.filePath);
if (!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) {
reportFailure(job, tr("Failed to open downloaded RSS file."));
return;
}
QXmlStreamReader xml(&fileRss); QXmlStreamReader xml(job.feedData);
bool foundChannel = false; bool foundChannel = false;
while (xml.readNextStartElement()) { while (xml.readNextStartElement()) {
if (xml.name() == "rss") { if (xml.name() == "rss") {
@ -533,14 +533,10 @@ void Parser::parseFeed(const ParsingJob &job)
return; return;
} }
// Clean up
fileRss.close();
emit feedParsingFinished(job.feedUrl, QString()); emit feedParsingFinished(job.feedUrl, QString());
Utils::Fs::forceRemove(job.filePath);
} }
void Parser::reportFailure(const ParsingJob &job, const QString &error) void Parser::reportFailure(const ParsingJob &job, const QString &error)
{ {
emit feedParsingFinished(job.feedUrl, error); emit feedParsingFinished(job.feedUrl, error);
Utils::Fs::forceRemove(job.filePath);
} }

View File

@ -31,14 +31,18 @@
#ifndef RSSPARSER_H #ifndef RSSPARSER_H
#define RSSPARSER_H #define RSSPARSER_H
#include <QHash>
#include <QMutex> #include <QMutex>
#include <QQueue> #include <QQueue>
#include <QThread> #include <QThread>
#include <QVariantHash>
#include <QWaitCondition> #include <QWaitCondition>
#include "rssarticle.h" class QXmlStreamReader;
namespace Rss namespace Rss
{
namespace Private
{ {
struct ParsingJob; struct ParsingJob;
@ -48,22 +52,21 @@ namespace Rss
public: public:
explicit Parser(QObject *parent = 0); explicit Parser(QObject *parent = 0);
virtual ~Parser(); ~Parser();
void parseFeedData(const QString &feedUrl, const QByteArray &feedData);
void clearFeedData(const QString &feedUrl);
signals: signals:
void newArticle(const QString &feedUrl, const QVariantHash &rssArticle); void newArticle(const QString &feedUrl, const QVariantHash &rssArticle);
void feedTitle(const QString &feedUrl, const QString &title); void feedTitle(const QString &feedUrl, const QString &title);
void feedParsingFinished(const QString &feedUrl, const QString &error); void feedParsingFinished(const QString &feedUrl, const QString &error);
public slots:
void parseRssFile(const QString &feedUrl, const QString &filePath);
void clearFeedData(const QString &feedUrl);
protected:
virtual void run();
private: private:
void run() override;
static QDateTime parseDate(const QString &string); static QDateTime parseDate(const QString &string);
void parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl); void parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl);
void parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl); void parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl);
void parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl); void parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl);
@ -78,5 +81,6 @@ namespace Rss
QHash<QString/*feedUrl*/, QString/*lastBuildDate*/> m_lastBuildDates; // Optimization QHash<QString/*feedUrl*/, QString/*lastBuildDate*/> m_lastBuildDates; // Optimization
}; };
} }
}
#endif // RSSPARSER_H #endif // RSSPARSER_H

View File

@ -120,13 +120,11 @@ bool Article::isRead() const
void Article::markAsRead() void Article::markAsRead()
{ {
if (m_read) return; if (!m_read) {
m_read = true; m_read = true;
m_parent->decrementUnreadCount();
m_parent->markAsDirty();
emit articleWasRead(); emit articleWasRead();
} }
}
const QString &Article::guid() const const QString &Article::guid() const
{ {

View File

@ -32,7 +32,6 @@
#ifndef RSSARTICLE_H #ifndef RSSARTICLE_H
#define RSSARTICLE_H #define RSSARTICLE_H
#include <QXmlStreamReader>
#include <QDateTime> #include <QDateTime>
#include <QVariantHash> #include <QVariantHash>
#include <QSharedPointer> #include <QSharedPointer>

View File

@ -40,9 +40,9 @@
#include "base/utils/fs.h" #include "base/utils/fs.h"
#include "base/net/downloadmanager.h" #include "base/net/downloadmanager.h"
#include "base/net/downloadhandler.h" #include "base/net/downloadhandler.h"
#include "private/rssparser.h"
#include "rssdownloadrulelist.h" #include "rssdownloadrulelist.h"
#include "rssarticle.h" #include "rssarticle.h"
#include "rssparser.h"
#include "rssfolder.h" #include "rssfolder.h"
#include "rssmanager.h" #include "rssmanager.h"
#include "rssfeed.h" #include "rssfeed.h"
@ -57,9 +57,8 @@ namespace Rss
using namespace Rss; using namespace Rss;
Feed::Feed(Manager *manager, Folder *parent, const QString &url) Feed::Feed(const QString &url, Manager *manager)
: m_manager(manager) : m_manager(manager)
, m_parent(parent)
, m_url (QUrl::fromEncoded(url.toUtf8()).toString()) , m_url (QUrl::fromEncoded(url.toUtf8()).toString())
, m_icon(":/icons/oxygen/application-rss+xml.png") , m_icon(":/icons/oxygen/application-rss+xml.png")
, m_unreadCount(0) , m_unreadCount(0)
@ -69,34 +68,26 @@ Feed::Feed(Manager *manager, Folder *parent, const QString &url)
{ {
qDebug() << Q_FUNC_INFO << m_url; qDebug() << Q_FUNC_INFO << m_url;
// Listen for new RSS downloads // Listen for new RSS downloads
connect(manager->rssParser(), SIGNAL(feedTitle(QString,QString)), SLOT(handleFeedTitle(QString,QString))); Private::Parser *const parser = m_manager->rssParser();
connect(manager->rssParser(), SIGNAL(newArticle(QString,QVariantHash)), SLOT(handleNewArticle(QString,QVariantHash))); connect(parser, SIGNAL(feedTitle(QString,QString)), SLOT(handleFeedTitle(QString,QString)));
connect(manager->rssParser(), SIGNAL(feedParsingFinished(QString,QString)), SLOT(handleFeedParsingFinished(QString,QString))); connect(parser, SIGNAL(newArticle(QString,QVariantHash)), SLOT(handleNewArticle(QString,QVariantHash)));
connect(parser, SIGNAL(feedParsingFinished(QString,QString)), SLOT(handleParsingFinished(QString,QString)));
// Download the RSS Feed icon // Download the RSS Feed icon
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(iconUrl(), true); Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(iconUrl(), true);
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString))); connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleIconDownloadFinished(QString, QString)));
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
m_iconUrl = handler->url();
// Load old RSS articles // Load old RSS articles
loadItemsFromDisk(); loadItemsFromDisk();
refresh();
} }
Feed::~Feed() Feed::~Feed()
{ {
if (!m_icon.startsWith(":/") && QFile::exists(m_icon)) if (!m_icon.startsWith(":/") && QFile::exists(m_icon))
Utils::Fs::forceRemove(m_icon); Utils::Fs::forceRemove(m_icon);
} m_manager->rssParser()->clearFeedData(m_url);
Folder *Feed::parent() const
{
return m_parent;
}
void Feed::setParent(Folder *parent)
{
m_parent = parent;
} }
void Feed::saveItemsToDisk() void Feed::saveItemsToDisk()
@ -104,7 +95,7 @@ void Feed::saveItemsToDisk()
qDebug() << Q_FUNC_INFO << m_url; qDebug() << Q_FUNC_INFO << m_url;
if (!m_dirty) return; if (!m_dirty) return;
markAsDirty(false); m_dirty = false;
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss"); QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
QVariantList oldItems; QVariantList oldItems;
@ -140,13 +131,15 @@ void Feed::addArticle(const ArticlePtr &article)
int maxArticles = Preferences::instance()->getRSSMaxArticlesPerFeed(); int maxArticles = Preferences::instance()->getRSSMaxArticlesPerFeed();
if (!m_articles.contains(article->guid())) { if (!m_articles.contains(article->guid())) {
markAsDirty(); m_dirty = true;
// Update unreadCount // Update unreadCount
if (!article->isRead()) if (!article->isRead())
++m_unreadCount; ++m_unreadCount;
// Insert in hash table // Insert in hash table
m_articles[article->guid()] = article; m_articles[article->guid()] = article;
if (!article->isRead()) // Optimization
connect(article.data(), SIGNAL(articleWasRead()), SLOT(handleArticleRead()), Qt::UniqueConnection);
// Insertion sort // Insertion sort
ArticleList::Iterator lowerBound = qLowerBound(m_articlesByDate.begin(), m_articlesByDate.end(), article, articleDateRecentThan); ArticleList::Iterator lowerBound = qLowerBound(m_articlesByDate.begin(), m_articlesByDate.end(), article, articleDateRecentThan);
m_articlesByDate.insert(lowerBound, article); m_articlesByDate.insert(lowerBound, article);
@ -162,7 +155,7 @@ void Feed::addArticle(const ArticlePtr &article)
// Check if article was inserted at the end of the list and will break max_articles limit // Check if article was inserted at the end of the list and will break max_articles limit
if (Preferences::instance()->isRssDownloadingEnabled()) { if (Preferences::instance()->isRssDownloadingEnabled()) {
if ((lbIndex < maxArticles) && !article->isRead()) if ((lbIndex < maxArticles) && !article->isRead())
downloadArticleTorrentIfMatching(m_manager->downloadRules(), article); downloadArticleTorrentIfMatching(article);
} }
} }
else { else {
@ -172,7 +165,7 @@ void Feed::addArticle(const ArticlePtr &article)
ArticlePtr skipped = m_articles.value(article->guid(), ArticlePtr()); ArticlePtr skipped = m_articles.value(article->guid(), ArticlePtr());
if (skipped) { if (skipped) {
if (!skipped->isRead()) if (!skipped->isRead())
downloadArticleTorrentIfMatching(m_manager->downloadRules(), skipped); downloadArticleTorrentIfMatching(skipped);
} }
} }
} }
@ -186,10 +179,9 @@ bool Feed::refresh()
} }
m_loading = true; m_loading = true;
// Download the RSS again // Download the RSS again
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(m_url, true); Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(m_url);
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString))); connect(handler, SIGNAL(downloadFinished(QString, QByteArray)), this, SLOT(handleRssDownloadFinished(QString, QByteArray)));
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString))); connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleRssDownloadFailed(QString, QString)));
m_url = handler->url(); // sync URL encoding
return true; return true;
} }
@ -290,11 +282,6 @@ void Feed::markAsRead()
m_manager->forwardFeedInfosChanged(m_url, displayName(), 0); m_manager->forwardFeedInfosChanged(m_url, displayName(), 0);
} }
void Feed::markAsDirty(bool dirty)
{
m_dirty = dirty;
}
uint Feed::unreadCount() const uint Feed::unreadCount() const
{ {
return m_unreadCount; return m_unreadCount;
@ -327,28 +314,27 @@ ArticleList Feed::unreadArticleListByDateDesc() const
QString Feed::iconUrl() const QString Feed::iconUrl() const
{ {
// XXX: This works for most sites but it is not perfect // XXX: This works for most sites but it is not perfect
return QString("http://") + QUrl(m_url).host() + QString("/favicon.ico"); return QString("http://%1/favicon.ico").arg(QUrl(m_url).host());
} }
// read and store the downloaded rss' informations void Feed::handleIconDownloadFinished(const QString &url, const QString &filePath)
void Feed::handleFinishedDownload(const QString &url, const QString &filePath)
{ {
if (url == m_url) { Q_UNUSED(url);
qDebug() << Q_FUNC_INFO << "Successfully downloaded RSS feed at" << url;
// Parse the download RSS
m_manager->rssParser()->parseRssFile(m_url, filePath);
}
else if (url == m_iconUrl) {
m_icon = filePath; m_icon = filePath;
qDebug() << Q_FUNC_INFO << "icon path:" << m_icon; qDebug() << Q_FUNC_INFO << "icon path:" << m_icon;
m_manager->forwardFeedIconChanged(m_url, m_icon); m_manager->forwardFeedIconChanged(m_url, m_icon);
} }
void Feed::handleRssDownloadFinished(const QString &url, const QByteArray &data)
{
qDebug() << Q_FUNC_INFO << "Successfully downloaded RSS feed at" << url;
// Parse the download RSS
m_manager->rssParser()->parseFeedData(m_url, data);
} }
void Feed::handleDownloadFailure(const QString &url, const QString &error) void Feed::handleRssDownloadFailed(const QString &url, const QString &error)
{ {
if (url != m_url) return;
m_inErrorState = true; m_inErrorState = true;
m_loading = false; m_loading = false;
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount); m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
@ -368,9 +354,10 @@ void Feed::handleFeedTitle(const QString &feedUrl, const QString &title)
m_manager->forwardFeedInfosChanged(feedUrl, title, m_unreadCount); m_manager->forwardFeedInfosChanged(feedUrl, title, m_unreadCount);
} }
void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const ArticlePtr &article) void Feed::downloadArticleTorrentIfMatching(const ArticlePtr &article)
{ {
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled()); Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
DownloadRuleList *rules = m_manager->downloadRules();
DownloadRulePtr matchingRule = rules->findMatchingRule(m_url, article->title()); DownloadRulePtr matchingRule = rules->findMatchingRule(m_url, article->title());
if (!matchingRule) return; if (!matchingRule) return;
@ -378,7 +365,6 @@ void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const Artic
QDateTime lastMatch = matchingRule->lastMatch(); QDateTime lastMatch = matchingRule->lastMatch();
if (lastMatch.isValid()) { if (lastMatch.isValid()) {
if (QDateTime::currentDateTime() < lastMatch.addDays(matchingRule->ignoreDays())) { if (QDateTime::currentDateTime() < lastMatch.addDays(matchingRule->ignoreDays())) {
connect(article.data(), SIGNAL(articleWasRead()), SLOT(handleArticleStateChanged()), Qt::UniqueConnection);
article->markAsRead(); article->markAsRead();
return; return;
} }
@ -396,8 +382,7 @@ void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const Artic
} }
Logger::instance()->addMessage(tr("Automatically downloading '%1' torrent from '%2' RSS feed...").arg(article->title()).arg(displayName())); Logger::instance()->addMessage(tr("Automatically downloading '%1' torrent from '%2' RSS feed...").arg(article->title()).arg(displayName()));
connect(BitTorrent::Session::instance(), SIGNAL(downloadFromUrlFinished(QString)), article.data(), SLOT(handleTorrentDownloadSuccess(const QString &)), Qt::UniqueConnection); if (BitTorrent::MagnetUri(torrentUrl).isValid())
if (BitTorrent::MagnetUri(torrent_url).isValid())
article->markAsRead(); article->markAsRead();
else else
connect(BitTorrent::Session::instance(), SIGNAL(downloadFromUrlFinished(QString)), article.data(), SLOT(handleTorrentDownloadSuccess(const QString&)), Qt::UniqueConnection); connect(BitTorrent::Session::instance(), SIGNAL(downloadFromUrlFinished(QString)), article.data(), SLOT(handleTorrentDownloadSuccess(const QString&)), Qt::UniqueConnection);
@ -415,10 +400,9 @@ void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const Artic
void Feed::recheckRssItemsForDownload() void Feed::recheckRssItemsForDownload()
{ {
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled()); Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
DownloadRuleList *rules = m_manager->downloadRules();
foreach (const ArticlePtr &article, m_articlesByDate) { foreach (const ArticlePtr &article, m_articlesByDate) {
if (!article->isRead()) if (!article->isRead())
downloadArticleTorrentIfMatching(rules, article); downloadArticleTorrentIfMatching(article);
} }
} }
@ -440,7 +424,7 @@ void Feed::handleNewArticle(const QString &feedUrl, const QVariantHash &articleD
//m_manager->forwardFeedContentChanged(m_url); //m_manager->forwardFeedContentChanged(m_url);
} }
void Feed::handleFeedParsingFinished(const QString &feedUrl, const QString &error) void Feed::handleParsingFinished(const QString &feedUrl, const QString &error)
{ {
if (feedUrl != m_url) return; if (feedUrl != m_url) return;
@ -459,12 +443,9 @@ void Feed::handleFeedParsingFinished(const QString &feedUrl, const QString &erro
saveItemsToDisk(); saveItemsToDisk();
} }
void Feed::handleArticleStateChanged() void Feed::handleArticleRead()
{
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
}
void Feed::decrementUnreadCount()
{ {
--m_unreadCount; --m_unreadCount;
m_dirty = true;
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
} }

View File

@ -58,11 +58,9 @@ namespace Rss
Q_OBJECT Q_OBJECT
public: public:
Feed(Manager *manager, Folder *parent, const QString &url); Feed(const QString &url, Manager *manager);
~Feed(); ~Feed();
Folder *parent() const;
void setParent(Folder *parent);
bool refresh(); bool refresh();
QString id() const; QString id() const;
void removeAllSettings(); void removeAllSettings();
@ -78,38 +76,35 @@ namespace Rss
ArticlePtr getItem(const QString &guid) const; ArticlePtr getItem(const QString &guid) const;
uint count() const; uint count() const;
void markAsRead(); void markAsRead();
void markAsDirty(bool dirty = true);
uint unreadCount() const; uint unreadCount() const;
ArticleList articleListByDateDesc() const; ArticleList articleListByDateDesc() const;
const ArticleHash &articleHash() const; const ArticleHash &articleHash() const;
ArticleList unreadArticleListByDateDesc() const; ArticleList unreadArticleListByDateDesc() const;
void decrementUnreadCount();
void recheckRssItemsForDownload(); void recheckRssItemsForDownload();
private slots: private slots:
void handleFinishedDownload(const QString &url, const QString &filePath); void handleIconDownloadFinished(const QString &url, const QString &filePath);
void handleDownloadFailure(const QString &url, const QString &error); void handleRssDownloadFinished(const QString &url, const QByteArray &data);
void handleRssDownloadFailed(const QString &url, const QString &error);
void handleFeedTitle(const QString &feedUrl, const QString &title); void handleFeedTitle(const QString &feedUrl, const QString &title);
void handleNewArticle(const QString &feedUrl, const QVariantHash &article); void handleNewArticle(const QString &feedUrl, const QVariantHash &article);
void handleFeedParsingFinished(const QString &feedUrl, const QString &error); void handleParsingFinished(const QString &feedUrl, const QString &error);
void handleArticleStateChanged(); void handleArticleRead();
private: private:
QString iconUrl() const; QString iconUrl() const;
void loadItemsFromDisk(); void loadItemsFromDisk();
void addArticle(const ArticlePtr &article); void addArticle(const ArticlePtr &article);
void downloadArticleTorrentIfMatching(DownloadRuleList *rules, const ArticlePtr &article); void downloadArticleTorrentIfMatching(const ArticlePtr &article);
private: private:
Manager *m_manager; Manager *m_manager;
ArticleHash m_articles; ArticleHash m_articles;
ArticleList m_articlesByDate; // Articles sorted by date (more recent first) ArticleList m_articlesByDate; // Articles sorted by date (more recent first)
Folder *m_parent;
QString m_title; QString m_title;
QString m_url; QString m_url;
QString m_alias; QString m_alias;
QString m_icon; QString m_icon;
QString m_iconUrl;
uint m_unreadCount; uint m_unreadCount;
bool m_dirty; bool m_dirty;
bool m_inErrorState; bool m_inErrorState;

View File

@ -36,11 +36,16 @@ using namespace Rss;
File::~File() {} File::~File() {}
Folder *File::parentFolder() const
{
return m_parent;
}
QStringList File::pathHierarchy() const QStringList File::pathHierarchy() const
{ {
QStringList path; QStringList path;
if (parent()) if (m_parent)
path << parent()->pathHierarchy(); path << m_parent->pathHierarchy();
path << id(); path << id();
return path; return path;
} }

View File

@ -55,25 +55,27 @@ namespace Rss
public: public:
virtual ~File(); virtual ~File();
virtual uint unreadCount() const = 0;
virtual QString displayName() const = 0;
virtual QString id() const = 0; virtual QString id() const = 0;
virtual QString displayName() const = 0;
virtual uint unreadCount() const = 0;
virtual QString iconPath() const = 0; virtual QString iconPath() const = 0;
virtual void rename(const QString &newName) = 0;
virtual void markAsRead() = 0;
virtual Folder *parent() const = 0;
virtual void setParent(Folder *parent) = 0;
virtual bool refresh() = 0;
virtual ArticleList articleListByDateDesc() const = 0; virtual ArticleList articleListByDateDesc() const = 0;
virtual ArticleList unreadArticleListByDateDesc() const = 0; virtual ArticleList unreadArticleListByDateDesc() const = 0;
virtual void rename(const QString &newName) = 0;
virtual void markAsRead() = 0;
virtual bool refresh() = 0;
virtual void removeAllSettings() = 0; virtual void removeAllSettings() = 0;
virtual void saveItemsToDisk() = 0; virtual void saveItemsToDisk() = 0;
virtual void recheckRssItemsForDownload() = 0; virtual void recheckRssItemsForDownload() = 0;
Folder *parentFolder() const;
QStringList pathHierarchy() const; QStringList pathHierarchy() const;
protected: protected:
uint m_unreadCount; friend class Folder;
Folder *m_parent = nullptr;
}; };
} }

View File

@ -40,24 +40,11 @@
using namespace Rss; using namespace Rss;
Folder::Folder(Folder *parent, const QString &name) Folder::Folder(const QString &name)
: m_parent(parent) : m_name(name)
, m_name(name)
{ {
} }
Folder::~Folder() {}
Folder *Folder::parent() const
{
return m_parent;
}
void Folder::setParent(Folder *parent)
{
m_parent = parent;
}
uint Folder::unreadCount() const uint Folder::unreadCount() const
{ {
uint nbUnread = 0; uint nbUnread = 0;
@ -78,31 +65,6 @@ void Folder::removeChild(const QString &childId)
} }
} }
FolderPtr Folder::addFolder(const QString &name)
{
FolderPtr subfolder;
if (!m_children.contains(name)) {
subfolder = FolderPtr(new Folder(this, name));
m_children[name] = subfolder;
}
else {
subfolder = qSharedPointerDynamicCast<Folder>(m_children.value(name));
}
return subfolder;
}
FeedPtr Folder::addStream(Manager *manager, const QString &url)
{
qDebug() << Q_FUNC_INFO << manager << url;
FeedPtr stream(new Feed(manager, this, url));
Q_ASSERT(stream);
qDebug() << "Stream URL is " << stream->url();
Q_ASSERT(!m_children.contains(stream->url()));
m_children[stream->url()] = stream;
stream->refresh();
return stream;
}
// Refresh All Children // Refresh All Children
bool Folder::refresh() bool Folder::refresh()
{ {
@ -176,7 +138,8 @@ void Folder::rename(const QString &newName)
Q_ASSERT(!m_parent->hasChild(newName)); Q_ASSERT(!m_parent->hasChild(newName));
if (!m_parent->hasChild(newName)) { if (!m_parent->hasChild(newName)) {
// Update parent // Update parent
m_parent->renameChildFolder(m_name, newName); FilePtr folder = m_parent->m_children.take(m_name);
m_parent->m_children[newName] = folder;
// Actually rename // Actually rename
m_name = newName; m_name = newName;
} }
@ -224,20 +187,17 @@ QHash<QString, FeedPtr> Folder::getAllFeedsAsHash() const
return ret; return ret;
} }
void Folder::addFile(const FilePtr &item) bool Folder::addFile(const FilePtr &item)
{ {
if (FeedPtr feed = qSharedPointerDynamicCast<Feed>(item)) { Q_ASSERT(!m_children.contains(item->id()));
Q_ASSERT(!m_children.contains(feed->url())); if (!m_children.contains(item->id())) {
m_children[feed->url()] = item; m_children[item->id()] = item;
qDebug("Added feed %s to folder ./%s", qPrintable(feed->url()), qPrintable(m_name));
}
else if (FolderPtr folder = qSharedPointerDynamicCast<Folder>(item)) {
Q_ASSERT(!m_children.contains(folder->displayName()));
m_children[folder->displayName()] = item;
qDebug("Added folder %s to folder ./%s", qPrintable(folder->displayName()), qPrintable(m_name));
}
// Update parent // Update parent
item->setParent(this); item->m_parent = this;
return true;
}
return false;
} }
void Folder::removeAllItems() void Folder::removeAllItems()
@ -245,6 +205,11 @@ void Folder::removeAllItems()
m_children.clear(); m_children.clear();
} }
FilePtr Folder::child(const QString &childId)
{
return m_children.value(childId);
}
void Folder::removeAllSettings() void Folder::removeAllSettings()
{ {
FileHash::ConstIterator it = m_children.begin(); FileHash::ConstIterator it = m_children.begin();
@ -274,13 +239,6 @@ bool Folder::hasChild(const QString &childId)
return m_children.contains(childId); return m_children.contains(childId);
} }
void Folder::renameChildFolder(const QString &oldName, const QString &newName)
{
Q_ASSERT(m_children.contains(oldName));
FilePtr folder = m_children.take(oldName);
m_children[newName] = folder;
}
FilePtr Folder::takeChild(const QString &childId) FilePtr Folder::takeChild(const QString &childId)
{ {
return m_children.take(childId); return m_children.take(childId);

View File

@ -48,19 +48,12 @@ namespace Rss
typedef QSharedPointer<Folder> FolderPtr; typedef QSharedPointer<Folder> FolderPtr;
typedef QList<FeedPtr> FeedList; typedef QList<FeedPtr> FeedList;
class Folder: public QObject, public File class Folder: public File
{ {
Q_OBJECT
public: public:
explicit Folder(Folder *parent = 0, const QString &name = QString()); explicit Folder(const QString &name = QString());
~Folder();
Folder *parent() const;
void setParent(Folder *parent);
uint unreadCount() const; uint unreadCount() const;
FeedPtr addStream(Manager *manager, const QString &url);
FolderPtr addFolder(const QString &name);
uint getNbFeeds() const; uint getNbFeeds() const;
FileList getContent() const; FileList getContent() const;
FeedList getAllFeeds() const; FeedList getAllFeeds() const;
@ -71,22 +64,20 @@ namespace Rss
bool hasChild(const QString &childId); bool hasChild(const QString &childId);
ArticleList articleListByDateDesc() const; ArticleList articleListByDateDesc() const;
ArticleList unreadArticleListByDateDesc() const; ArticleList unreadArticleListByDateDesc() const;
void removeAllSettings();
void saveItemsToDisk();
void removeAllItems();
void renameChildFolder(const QString &oldName, const QString &newName);
FilePtr takeChild(const QString &childId);
void recheckRssItemsForDownload();
public slots:
bool refresh();
void addFile(const FilePtr &item);
void removeChild(const QString &childId);
void rename(const QString &newName); void rename(const QString &newName);
void markAsRead(); void markAsRead();
bool refresh();
void removeAllSettings();
void saveItemsToDisk();
void recheckRssItemsForDownload();
void removeAllItems();
FilePtr child(const QString &childId);
FilePtr takeChild(const QString &childId);
bool addFile(const FilePtr &item);
void removeChild(const QString &childId);
private: private:
Folder *m_parent;
QString m_name; QString m_name;
FileHash m_children; FileHash m_children;
}; };

View File

@ -33,19 +33,23 @@
#include "base/logger.h" #include "base/logger.h"
#include "base/preferences.h" #include "base/preferences.h"
#include "private/rssparser.h"
#include "rssfolder.h"
#include "rssfeed.h" #include "rssfeed.h"
#include "rssarticle.h" #include "rssarticle.h"
#include "rssdownloadrulelist.h" #include "rssdownloadrulelist.h"
#include "rssparser.h"
#include "rssmanager.h" #include "rssmanager.h"
static const int MSECS_PER_MIN = 60000; static const int MSECS_PER_MIN = 60000;
using namespace Rss; using namespace Rss;
using namespace Rss::Private;
Manager::Manager() Manager::Manager(QObject *parent)
: m_downloadRules(new DownloadRuleList) : QObject(parent)
, m_downloadRules(new DownloadRuleList)
, m_rssParser(new Parser(this)) , m_rssParser(new Parser(this))
, m_rootFolder(new Folder)
{ {
connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(refresh())); connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(refresh()));
m_refreshInterval = Preferences::instance()->getRSSRefreshInterval(); m_refreshInterval = Preferences::instance()->getRSSRefreshInterval();
@ -57,16 +61,12 @@ Manager::~Manager()
qDebug("Deleting RSSManager..."); qDebug("Deleting RSSManager...");
delete m_downloadRules; delete m_downloadRules;
delete m_rssParser; delete m_rssParser;
saveItemsToDisk(); m_rootFolder->saveItemsToDisk();
saveStreamList(); saveStreamList();
m_rootFolder.clear();
qDebug("RSSManager deleted"); qDebug("RSSManager deleted");
} }
Parser *Manager::rssParser() const
{
return m_rssParser;
}
void Manager::updateRefreshInterval(uint val) void Manager::updateRefreshInterval(uint val)
{ {
if (m_refreshInterval != val) { if (m_refreshInterval != val) {
@ -95,14 +95,22 @@ void Manager::loadStreamList()
const QString feedUrl = path.takeLast(); const QString feedUrl = path.takeLast();
qDebug() << "Feed URL:" << feedUrl; qDebug() << "Feed URL:" << feedUrl;
// Create feed path (if it does not exists) // Create feed path (if it does not exists)
Folder *feedParent = this; FolderPtr feedParent = m_rootFolder;
foreach (const QString &folderName, path) { foreach (const QString &folderName, path) {
if (!feedParent->hasChild(folderName)) {
qDebug() << "Adding parent folder:" << folderName; qDebug() << "Adding parent folder:" << folderName;
feedParent = feedParent->addFolder(folderName).data(); FolderPtr folder(new Folder(folderName));
feedParent->addFile(folder);
feedParent = folder;
}
else {
feedParent = qSharedPointerDynamicCast<Folder>(feedParent->child(folderName));
}
} }
// Create feed // Create feed
qDebug() << "Adding feed to parent folder"; qDebug() << "Adding feed to parent folder";
FeedPtr stream = feedParent->addStream(this, feedUrl); FeedPtr stream(new Feed(feedUrl, this));
feedParent->addFile(stream);
const QString &alias = aliases[i]; const QString &alias = aliases[i];
if (!alias.isEmpty()) if (!alias.isEmpty())
stream->rename(alias); stream->rename(alias);
@ -128,7 +136,7 @@ void Manager::forwardFeedIconChanged(const QString &url, const QString &iconPath
void Manager::moveFile(const FilePtr &file, const FolderPtr &destinationFolder) void Manager::moveFile(const FilePtr &file, const FolderPtr &destinationFolder)
{ {
Folder *srcFolder = file->parent(); Folder *srcFolder = file->parentFolder();
if (destinationFolder != srcFolder) { if (destinationFolder != srcFolder) {
// Remove reference in old folder // Remove reference in old folder
srcFolder->takeChild(file->id()); srcFolder->takeChild(file->id());
@ -144,7 +152,7 @@ void Manager::saveStreamList() const
{ {
QStringList streamsUrl; QStringList streamsUrl;
QStringList aliases; QStringList aliases;
FeedList streams = getAllFeeds(); FeedList streams = m_rootFolder->getAllFeeds();
foreach (const FeedPtr &stream, streams) { foreach (const FeedPtr &stream, streams) {
// This backslash has nothing to do with path handling // This backslash has nothing to do with path handling
QString streamPath = stream->pathHierarchy().join("\\"); QString streamPath = stream->pathHierarchy().join("\\");
@ -164,3 +172,18 @@ DownloadRuleList *Manager::downloadRules() const
Q_ASSERT(m_downloadRules); Q_ASSERT(m_downloadRules);
return m_downloadRules; return m_downloadRules;
} }
FolderPtr Manager::rootFolder() const
{
return m_rootFolder;
}
Parser *Manager::rssParser() const
{
return m_rssParser;
}
void Manager::refresh()
{
m_rootFolder->refresh();
}

View File

@ -32,31 +32,44 @@
#ifndef RSSMANAGER_H #ifndef RSSMANAGER_H
#define RSSMANAGER_H #define RSSMANAGER_H
#include <QObject>
#include <QTimer> #include <QTimer>
#include <QSharedPointer> #include <QSharedPointer>
#include "rssfolder.h"
namespace Rss namespace Rss
{ {
class DownloadRuleList; class DownloadRuleList;
class Parser; class File;
class Folder;
class Feed;
class Manager; class Manager;
typedef QSharedPointer<File> FilePtr;
typedef QSharedPointer<Folder> FolderPtr;
typedef QSharedPointer<Feed> FeedPtr;
namespace Private
{
class Parser;
}
typedef QSharedPointer<Manager> ManagerPtr; typedef QSharedPointer<Manager> ManagerPtr;
class Manager: public Folder class Manager: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Manager(); explicit Manager(QObject *parent = 0);
~Manager(); ~Manager();
Parser *rssParser() const;
DownloadRuleList *downloadRules() const; DownloadRuleList *downloadRules() const;
FolderPtr rootFolder() const;
Private::Parser *rssParser() const;
public slots: public slots:
void refresh();
void loadStreamList(); void loadStreamList();
void saveStreamList() const; void saveStreamList() const;
void forwardFeedContentChanged(const QString &url); void forwardFeedContentChanged(const QString &url);
@ -74,7 +87,8 @@ namespace Rss
QTimer m_refreshTimer; QTimer m_refreshTimer;
uint m_refreshInterval; uint m_refreshInterval;
DownloadRuleList *m_downloadRules; DownloadRuleList *m_downloadRules;
Parser *m_rssParser; Private::Parser *m_rssParser;
FolderPtr m_rootFolder;
}; };
} }

View File

@ -39,6 +39,7 @@
#include "base/rss/rssdownloadrulelist.h" #include "base/rss/rssdownloadrulelist.h"
#include "base/preferences.h" #include "base/preferences.h"
#include "base/rss/rssmanager.h" #include "base/rss/rssmanager.h"
#include "base/rss/rssfolder.h"
#include "base/rss/rssfeed.h" #include "base/rss/rssfeed.h"
#include "guiiconprovider.h" #include "guiiconprovider.h"
#include "autoexpandabledialog.h" #include "autoexpandabledialog.h"
@ -524,7 +525,7 @@ void AutomatedRssDownloader::updateMatchingArticles()
Rss::ManagerPtr manager = m_manager.toStrongRef(); Rss::ManagerPtr manager = m_manager.toStrongRef();
if (!manager) if (!manager)
return; return;
const QHash<QString, Rss::FeedPtr> all_feeds = manager->getAllFeedsAsHash(); const QHash<QString, Rss::FeedPtr> all_feeds = manager->rootFolder()->getAllFeedsAsHash();
saveEditedRule(); saveEditedRule();
foreach (const QListWidgetItem *rule_item, ui->listRules->selectedItems()) { foreach (const QListWidgetItem *rule_item, ui->listRules->selectedItems()) {

View File

@ -29,6 +29,7 @@
*/ */
#include "base/rss/rssmanager.h" #include "base/rss/rssmanager.h"
#include "base/rss/rssfolder.h"
#include "base/rss/rssfeed.h" #include "base/rss/rssfeed.h"
#include "guiiconprovider.h" #include "guiiconprovider.h"
#include "feedlistwidget.h" #include "feedlistwidget.h"
@ -40,9 +41,9 @@ FeedListWidget::FeedListWidget(QWidget *parent, const Rss::ManagerPtr& rssmanage
setColumnCount(1); setColumnCount(1);
headerItem()->setText(0, tr("RSS feeds")); headerItem()->setText(0, tr("RSS feeds"));
m_unreadStickyItem = new QTreeWidgetItem(this); m_unreadStickyItem = new QTreeWidgetItem(this);
m_unreadStickyItem->setText(0, tr("Unread") + QString::fromUtf8(" (") + QString::number(rssmanager->unreadCount())+ QString(")")); m_unreadStickyItem->setText(0, tr("Unread") + QString::fromUtf8(" (") + QString::number(rssmanager->rootFolder()->unreadCount()) + QString(")"));
m_unreadStickyItem->setData(0,Qt::DecorationRole, GuiIconProvider::instance()->getIcon("mail-folder-inbox")); m_unreadStickyItem->setData(0,Qt::DecorationRole, GuiIconProvider::instance()->getIcon("mail-folder-inbox"));
itemAdded(m_unreadStickyItem, rssmanager); itemAdded(m_unreadStickyItem, rssmanager->rootFolder());
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(updateCurrentFeed(QTreeWidgetItem*))); connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(updateCurrentFeed(QTreeWidgetItem*)));
setCurrentItem(m_unreadStickyItem); setCurrentItem(m_unreadStickyItem);
} }
@ -202,7 +203,7 @@ void FeedListWidget::dropEvent(QDropEvent *event) {
dest_folder = qSharedPointerCast<Rss::Folder>(getRSSItem(dest_folder_item)); dest_folder = qSharedPointerCast<Rss::Folder>(getRSSItem(dest_folder_item));
folders_altered << dest_folder_item; folders_altered << dest_folder_item;
} else { } else {
dest_folder = m_rssManager; dest_folder = m_rssManager->rootFolder();
} }
QList<QTreeWidgetItem *> src_items = selectedItems(); QList<QTreeWidgetItem *> src_items = selectedItems();
// Check if there is not going to overwrite another file // Check if there is not going to overwrite another file

View File

@ -47,7 +47,6 @@
#include "base/rss/rssmanager.h" #include "base/rss/rssmanager.h"
#include "base/rss/rssfolder.h" #include "base/rss/rssfolder.h"
#include "base/rss/rssarticle.h" #include "base/rss/rssarticle.h"
#include "base/rss/rssparser.h"
#include "base/rss/rssfeed.h" #include "base/rss/rssfeed.h"
#include "automatedrssdownloader.h" #include "automatedrssdownloader.h"
#include "guiiconprovider.h" #include "guiiconprovider.h"
@ -79,7 +78,7 @@ void RSSImp::displayRSSListMenu(const QPoint& pos)
myRSSListMenu.addAction(actionMark_items_read); myRSSListMenu.addAction(actionMark_items_read);
myRSSListMenu.addSeparator(); myRSSListMenu.addSeparator();
if (selectedItems.size() == 1) { if (selectedItems.size() == 1) {
if (m_feedList->getRSSItem(selectedItems.first()) != m_rssManager) { if (m_feedList->getRSSItem(selectedItems.first()) != m_rssManager->rootFolder()) {
myRSSListMenu.addAction(actionRename); myRSSListMenu.addAction(actionRename);
myRSSListMenu.addAction(actionDelete); myRSSListMenu.addAction(actionDelete);
myRSSListMenu.addSeparator(); myRSSListMenu.addSeparator();
@ -167,14 +166,15 @@ void RSSImp::askNewFolder()
Q_ASSERT(rss_parent); Q_ASSERT(rss_parent);
} }
else { else {
rss_parent = m_rssManager; rss_parent = m_rssManager->rootFolder();
} }
bool ok; bool ok;
QString new_name = AutoExpandableDialog::getText(this, tr("Please choose a folder name"), tr("Folder name:"), QLineEdit::Normal, tr("New folder"), &ok); QString new_name = AutoExpandableDialog::getText(this, tr("Please choose a folder name"), tr("Folder name:"), QLineEdit::Normal, tr("New folder"), &ok);
if (!ok) if (!ok || rss_parent->hasChild(new_name))
return; return;
Rss::FolderPtr newFolder = rss_parent->addFolder(new_name); Rss::FolderPtr newFolder(new Rss::Folder(new_name));
rss_parent->addFile(newFolder);
QTreeWidgetItem* folderItem = createFolderListItem(newFolder); QTreeWidgetItem* folderItem = createFolderListItem(newFolder);
if (parent_item) if (parent_item)
parent_item->addChild(folderItem); parent_item->addChild(folderItem);
@ -207,7 +207,7 @@ void RSSImp::on_newFeedButton_clicked()
if (parent_item) if (parent_item)
rss_parent = qSharedPointerCast<Rss::Folder>(m_feedList->getRSSItem(parent_item)); rss_parent = qSharedPointerCast<Rss::Folder>(m_feedList->getRSSItem(parent_item));
else else
rss_parent = m_rssManager; rss_parent = m_rssManager->rootFolder();
// Ask for feed URL // Ask for feed URL
bool ok; bool ok;
QString clip_txt = qApp->clipboard()->text(); QString clip_txt = qApp->clipboard()->text();
@ -229,7 +229,9 @@ void RSSImp::on_newFeedButton_clicked()
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
Rss::FeedPtr stream = rss_parent->addStream(m_rssManager.data(), newUrl);
Rss::FeedPtr stream(new Rss::Feed(newUrl, m_rssManager.data()));
rss_parent->addFile(stream);
// Create TreeWidget item // Create TreeWidget item
QTreeWidgetItem* item = createFolderListItem(stream); QTreeWidgetItem* item = createFolderListItem(stream);
if (parent_item) if (parent_item)
@ -265,17 +267,13 @@ void RSSImp::deleteSelectedItems()
// Notify TreeWidget // Notify TreeWidget
m_feedList->itemAboutToBeRemoved(item); m_feedList->itemAboutToBeRemoved(item);
// Actually delete the item // Actually delete the item
rss_item->parent()->removeChild(rss_item->id()); rss_item->parentFolder()->removeChild(rss_item->id());
delete item; delete item;
// Update parents count // Update parents count
while (parent && parent != m_feedList->invisibleRootItem()) { while (parent && (parent != m_feedList->invisibleRootItem())) {
updateItemInfos(parent); updateItemInfos(parent);
parent = parent->parent(); parent = parent->parent();
} }
// Clear feed data from RSS parser (possible caching).
Rss::Feed* rssFeed = dynamic_cast<Rss::Feed*>(rss_item.data());
if (rssFeed)
m_rssManager->rssParser()->clearFeedData(rssFeed->url());
} }
m_rssManager->saveStreamList(); m_rssManager->saveStreamList();
// Update Unread items // Update Unread items
@ -406,7 +404,7 @@ void RSSImp::renameSelectedRssFile()
newName = AutoExpandableDialog::getText(this, tr("Please choose a new name for this RSS feed"), tr("New feed name:"), QLineEdit::Normal, m_feedList->getRSSItem(item)->displayName(), &ok); newName = AutoExpandableDialog::getText(this, tr("Please choose a new name for this RSS feed"), tr("New feed name:"), QLineEdit::Normal, m_feedList->getRSSItem(item)->displayName(), &ok);
// Check if name is already taken // Check if name is already taken
if (ok) { if (ok) {
if (rss_item->parent()->hasChild(newName)) { if (rss_item->parentFolder()->hasChild(newName)) {
QMessageBox::warning(0, tr("Name already in use"), tr("This name is already used by another item, please choose another one.")); QMessageBox::warning(0, tr("Name already in use"), tr("This name is already used by another item, please choose another one."));
ok = false; ok = false;
} }
@ -489,7 +487,7 @@ void RSSImp::fillFeedsList(QTreeWidgetItem* parent, const Rss::FolderPtr& rss_pa
if (parent) if (parent)
children = rss_parent->getContent(); children = rss_parent->getContent();
else else
children = m_rssManager->getContent(); children = m_rssManager->rootFolder()->getContent();
foreach (const Rss::FilePtr& rssFile, children) { foreach (const Rss::FilePtr& rssFile, children) {
QTreeWidgetItem* item = createFolderListItem(rssFile); QTreeWidgetItem* item = createFolderListItem(rssFile);
Q_ASSERT(item); Q_ASSERT(item);
@ -546,7 +544,7 @@ void RSSImp::populateArticleList(QTreeWidgetItem* item)
qDebug("Getting the list of news"); qDebug("Getting the list of news");
Rss::ArticleList articles; Rss::ArticleList articles;
if (rss_item == m_rssManager) if (rss_item == m_rssManager->rootFolder())
articles = rss_item->unreadArticleListByDateDesc(); articles = rss_item->unreadArticleListByDateDesc();
else else
articles = rss_item->articleListByDateDesc(); articles = rss_item->articleListByDateDesc();
@ -655,7 +653,7 @@ void RSSImp::updateItemInfos(QTreeWidgetItem *item)
return; return;
QString name; QString name;
if (rss_item == m_rssManager) { if (rss_item == m_rssManager->rootFolder()) {
name = tr("Unread"); name = tr("Unread");
emit updateRSSCount(rss_item->unreadCount()); emit updateRSSCount(rss_item->unreadCount());
} }
@ -799,7 +797,7 @@ void RSSImp::on_rssDownloaderBtn_clicked()
AutomatedRssDownloader dlg(m_rssManager, this); AutomatedRssDownloader dlg(m_rssManager, this);
dlg.exec(); dlg.exec();
if (dlg.isRssDownloaderEnabled()) { if (dlg.isRssDownloaderEnabled()) {
m_rssManager->recheckRssItemsForDownload(); m_rssManager->rootFolder()->recheckRssItemsForDownload();
refreshAllFeeds(); refreshAllFeeds();
} }
} }