mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-23 04:54:18 +00:00
Redesign RSS base classes.
This commit is contained in:
parent
6f7ae728eb
commit
28ed981082
@ -43,7 +43,7 @@ HEADERS += \
|
||||
$$PWD/rss/rssarticle.h \
|
||||
$$PWD/rss/rssdownloadrule.h \
|
||||
$$PWD/rss/rssdownloadrulelist.h \
|
||||
$$PWD/rss/rssparser.h \
|
||||
$$PWD/rss/private/rssparser.h \
|
||||
$$PWD/utils/fs.h \
|
||||
$$PWD/utils/gzip.h \
|
||||
$$PWD/utils/misc.h \
|
||||
@ -94,7 +94,7 @@ SOURCES += \
|
||||
$$PWD/rss/rssdownloadrule.cpp \
|
||||
$$PWD/rss/rssdownloadrulelist.cpp \
|
||||
$$PWD/rss/rssfile.cpp \
|
||||
$$PWD/rss/rssparser.cpp \
|
||||
$$PWD/rss/private/rssparser.cpp \
|
||||
$$PWD/utils/fs.cpp \
|
||||
$$PWD/utils/gzip.cpp \
|
||||
$$PWD/utils/misc.cpp \
|
||||
|
@ -29,22 +29,27 @@
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include "base/utils/fs.h"
|
||||
#include "rssparser.h"
|
||||
|
||||
namespace Rss
|
||||
{
|
||||
namespace Private
|
||||
{
|
||||
struct ParsingJob
|
||||
{
|
||||
QString feedUrl;
|
||||
QString filePath;
|
||||
QByteArray feedData;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static const char shortDay[][4] = {
|
||||
"Mon", "Tue", "Wed",
|
||||
@ -64,7 +69,7 @@ static const char shortMonth[][4] = {
|
||||
"Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
using namespace Rss;
|
||||
using namespace Rss::Private;
|
||||
|
||||
Parser::Parser(QObject *parent)
|
||||
: QThread(parent)
|
||||
@ -227,11 +232,11 @@ QDateTime Parser::parseDate(const QString &string)
|
||||
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();
|
||||
ParsingJob job = { feedUrl, Utils::Fs::fromNativePath(filePath) };
|
||||
ParsingJob job = { feedUrl, feedData };
|
||||
m_queue.enqueue(job);
|
||||
// Wake up thread.
|
||||
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
|
||||
void Parser::parseFeed(const ParsingJob &job)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << job.feedUrl << job.filePath;
|
||||
QFile fileRss(job.filePath);
|
||||
if (!fileRss.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
reportFailure(job, tr("Failed to open downloaded RSS file."));
|
||||
return;
|
||||
}
|
||||
qDebug() << Q_FUNC_INFO << job.feedUrl;
|
||||
|
||||
QXmlStreamReader xml(&fileRss);
|
||||
QXmlStreamReader xml(job.feedData);
|
||||
bool foundChannel = false;
|
||||
while (xml.readNextStartElement()) {
|
||||
if (xml.name() == "rss") {
|
||||
@ -533,14 +533,10 @@ void Parser::parseFeed(const ParsingJob &job)
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
fileRss.close();
|
||||
emit feedParsingFinished(job.feedUrl, QString());
|
||||
Utils::Fs::forceRemove(job.filePath);
|
||||
}
|
||||
|
||||
void Parser::reportFailure(const ParsingJob &job, const QString &error)
|
||||
{
|
||||
emit feedParsingFinished(job.feedUrl, error);
|
||||
Utils::Fs::forceRemove(job.filePath);
|
||||
}
|
@ -31,14 +31,18 @@
|
||||
#ifndef RSSPARSER_H
|
||||
#define RSSPARSER_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QMutex>
|
||||
#include <QQueue>
|
||||
#include <QThread>
|
||||
#include <QVariantHash>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "rssarticle.h"
|
||||
class QXmlStreamReader;
|
||||
|
||||
namespace Rss
|
||||
{
|
||||
namespace Private
|
||||
{
|
||||
struct ParsingJob;
|
||||
|
||||
@ -48,22 +52,21 @@ namespace Rss
|
||||
|
||||
public:
|
||||
explicit Parser(QObject *parent = 0);
|
||||
virtual ~Parser();
|
||||
~Parser();
|
||||
|
||||
void parseFeedData(const QString &feedUrl, const QByteArray &feedData);
|
||||
void clearFeedData(const QString &feedUrl);
|
||||
|
||||
signals:
|
||||
void newArticle(const QString &feedUrl, const QVariantHash &rssArticle);
|
||||
void feedTitle(const QString &feedUrl, const QString &title);
|
||||
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:
|
||||
void run() override;
|
||||
|
||||
static QDateTime parseDate(const QString &string);
|
||||
|
||||
void parseRssArticle(QXmlStreamReader &xml, const QString &feedUrl);
|
||||
void parseRSSChannel(QXmlStreamReader &xml, const QString &feedUrl);
|
||||
void parseAtomArticle(QXmlStreamReader &xml, const QString &feedUrl, const QString &baseUrl);
|
||||
@ -78,5 +81,6 @@ namespace Rss
|
||||
QHash<QString/*feedUrl*/, QString/*lastBuildDate*/> m_lastBuildDates; // Optimization
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RSSPARSER_H
|
@ -120,13 +120,11 @@ bool Article::isRead() const
|
||||
|
||||
void Article::markAsRead()
|
||||
{
|
||||
if (m_read) return;
|
||||
|
||||
if (!m_read) {
|
||||
m_read = true;
|
||||
m_parent->decrementUnreadCount();
|
||||
m_parent->markAsDirty();
|
||||
emit articleWasRead();
|
||||
}
|
||||
}
|
||||
|
||||
const QString &Article::guid() const
|
||||
{
|
||||
|
@ -32,7 +32,6 @@
|
||||
#ifndef RSSARTICLE_H
|
||||
#define RSSARTICLE_H
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QDateTime>
|
||||
#include <QVariantHash>
|
||||
#include <QSharedPointer>
|
||||
|
@ -40,9 +40,9 @@
|
||||
#include "base/utils/fs.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/net/downloadhandler.h"
|
||||
#include "private/rssparser.h"
|
||||
#include "rssdownloadrulelist.h"
|
||||
#include "rssarticle.h"
|
||||
#include "rssparser.h"
|
||||
#include "rssfolder.h"
|
||||
#include "rssmanager.h"
|
||||
#include "rssfeed.h"
|
||||
@ -57,9 +57,8 @@ 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_parent(parent)
|
||||
, m_url (QUrl::fromEncoded(url.toUtf8()).toString())
|
||||
, m_icon(":/icons/oxygen/application-rss+xml.png")
|
||||
, m_unreadCount(0)
|
||||
@ -69,34 +68,26 @@ Feed::Feed(Manager *manager, Folder *parent, const QString &url)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << m_url;
|
||||
// Listen for new RSS downloads
|
||||
connect(manager->rssParser(), SIGNAL(feedTitle(QString,QString)), SLOT(handleFeedTitle(QString,QString)));
|
||||
connect(manager->rssParser(), SIGNAL(newArticle(QString,QVariantHash)), SLOT(handleNewArticle(QString,QVariantHash)));
|
||||
connect(manager->rssParser(), SIGNAL(feedParsingFinished(QString,QString)), SLOT(handleFeedParsingFinished(QString,QString)));
|
||||
Private::Parser *const parser = m_manager->rssParser();
|
||||
connect(parser, SIGNAL(feedTitle(QString,QString)), SLOT(handleFeedTitle(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
|
||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(iconUrl(), true);
|
||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString)));
|
||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
||||
m_iconUrl = handler->url();
|
||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleIconDownloadFinished(QString, QString)));
|
||||
|
||||
// Load old RSS articles
|
||||
loadItemsFromDisk();
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
Feed::~Feed()
|
||||
{
|
||||
if (!m_icon.startsWith(":/") && QFile::exists(m_icon))
|
||||
Utils::Fs::forceRemove(m_icon);
|
||||
}
|
||||
|
||||
Folder *Feed::parent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
void Feed::setParent(Folder *parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
m_manager->rssParser()->clearFeedData(m_url);
|
||||
}
|
||||
|
||||
void Feed::saveItemsToDisk()
|
||||
@ -104,7 +95,7 @@ void Feed::saveItemsToDisk()
|
||||
qDebug() << Q_FUNC_INFO << m_url;
|
||||
if (!m_dirty) return;
|
||||
|
||||
markAsDirty(false);
|
||||
m_dirty = false;
|
||||
|
||||
QIniSettings qBTRSS("qBittorrent", "qBittorrent-rss");
|
||||
QVariantList oldItems;
|
||||
@ -140,13 +131,15 @@ void Feed::addArticle(const ArticlePtr &article)
|
||||
int maxArticles = Preferences::instance()->getRSSMaxArticlesPerFeed();
|
||||
|
||||
if (!m_articles.contains(article->guid())) {
|
||||
markAsDirty();
|
||||
m_dirty = true;
|
||||
|
||||
// Update unreadCount
|
||||
if (!article->isRead())
|
||||
++m_unreadCount;
|
||||
// Insert in hash table
|
||||
m_articles[article->guid()] = article;
|
||||
if (!article->isRead()) // Optimization
|
||||
connect(article.data(), SIGNAL(articleWasRead()), SLOT(handleArticleRead()), Qt::UniqueConnection);
|
||||
// Insertion sort
|
||||
ArticleList::Iterator lowerBound = qLowerBound(m_articlesByDate.begin(), m_articlesByDate.end(), article, articleDateRecentThan);
|
||||
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
|
||||
if (Preferences::instance()->isRssDownloadingEnabled()) {
|
||||
if ((lbIndex < maxArticles) && !article->isRead())
|
||||
downloadArticleTorrentIfMatching(m_manager->downloadRules(), article);
|
||||
downloadArticleTorrentIfMatching(article);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -172,7 +165,7 @@ void Feed::addArticle(const ArticlePtr &article)
|
||||
ArticlePtr skipped = m_articles.value(article->guid(), ArticlePtr());
|
||||
if (skipped) {
|
||||
if (!skipped->isRead())
|
||||
downloadArticleTorrentIfMatching(m_manager->downloadRules(), skipped);
|
||||
downloadArticleTorrentIfMatching(skipped);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,10 +179,9 @@ bool Feed::refresh()
|
||||
}
|
||||
m_loading = true;
|
||||
// Download the RSS again
|
||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(m_url, true);
|
||||
connect(handler, SIGNAL(downloadFinished(QString, QString)), this, SLOT(handleFinishedDownload(QString, QString)));
|
||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleDownloadFailure(QString, QString)));
|
||||
m_url = handler->url(); // sync URL encoding
|
||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(m_url);
|
||||
connect(handler, SIGNAL(downloadFinished(QString, QByteArray)), this, SLOT(handleRssDownloadFinished(QString, QByteArray)));
|
||||
connect(handler, SIGNAL(downloadFailed(QString, QString)), this, SLOT(handleRssDownloadFailed(QString, QString)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -290,11 +282,6 @@ void Feed::markAsRead()
|
||||
m_manager->forwardFeedInfosChanged(m_url, displayName(), 0);
|
||||
}
|
||||
|
||||
void Feed::markAsDirty(bool dirty)
|
||||
{
|
||||
m_dirty = dirty;
|
||||
}
|
||||
|
||||
uint Feed::unreadCount() const
|
||||
{
|
||||
return m_unreadCount;
|
||||
@ -327,28 +314,27 @@ ArticleList Feed::unreadArticleListByDateDesc() const
|
||||
QString Feed::iconUrl() const
|
||||
{
|
||||
// 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::handleFinishedDownload(const QString &url, const QString &filePath)
|
||||
void Feed::handleIconDownloadFinished(const QString &url, const QString &filePath)
|
||||
{
|
||||
if (url == m_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) {
|
||||
Q_UNUSED(url);
|
||||
|
||||
m_icon = filePath;
|
||||
qDebug() << Q_FUNC_INFO << "icon path:" << 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_loading = false;
|
||||
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);
|
||||
}
|
||||
|
||||
void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const ArticlePtr &article)
|
||||
void Feed::downloadArticleTorrentIfMatching(const ArticlePtr &article)
|
||||
{
|
||||
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
|
||||
DownloadRuleList *rules = m_manager->downloadRules();
|
||||
DownloadRulePtr matchingRule = rules->findMatchingRule(m_url, article->title());
|
||||
if (!matchingRule) return;
|
||||
|
||||
@ -378,7 +365,6 @@ void Feed::downloadArticleTorrentIfMatching(DownloadRuleList *rules, const Artic
|
||||
QDateTime lastMatch = matchingRule->lastMatch();
|
||||
if (lastMatch.isValid()) {
|
||||
if (QDateTime::currentDateTime() < lastMatch.addDays(matchingRule->ignoreDays())) {
|
||||
connect(article.data(), SIGNAL(articleWasRead()), SLOT(handleArticleStateChanged()), Qt::UniqueConnection);
|
||||
article->markAsRead();
|
||||
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()));
|
||||
connect(BitTorrent::Session::instance(), SIGNAL(downloadFromUrlFinished(QString)), article.data(), SLOT(handleTorrentDownloadSuccess(const QString &)), Qt::UniqueConnection);
|
||||
if (BitTorrent::MagnetUri(torrent_url).isValid())
|
||||
if (BitTorrent::MagnetUri(torrentUrl).isValid())
|
||||
article->markAsRead();
|
||||
else
|
||||
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()
|
||||
{
|
||||
Q_ASSERT(Preferences::instance()->isRssDownloadingEnabled());
|
||||
DownloadRuleList *rules = m_manager->downloadRules();
|
||||
foreach (const ArticlePtr &article, m_articlesByDate) {
|
||||
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);
|
||||
}
|
||||
|
||||
void Feed::handleFeedParsingFinished(const QString &feedUrl, const QString &error)
|
||||
void Feed::handleParsingFinished(const QString &feedUrl, const QString &error)
|
||||
{
|
||||
if (feedUrl != m_url) return;
|
||||
|
||||
@ -459,12 +443,9 @@ void Feed::handleFeedParsingFinished(const QString &feedUrl, const QString &erro
|
||||
saveItemsToDisk();
|
||||
}
|
||||
|
||||
void Feed::handleArticleStateChanged()
|
||||
{
|
||||
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
|
||||
}
|
||||
|
||||
void Feed::decrementUnreadCount()
|
||||
void Feed::handleArticleRead()
|
||||
{
|
||||
--m_unreadCount;
|
||||
m_dirty = true;
|
||||
m_manager->forwardFeedInfosChanged(m_url, displayName(), m_unreadCount);
|
||||
}
|
||||
|
@ -58,11 +58,9 @@ namespace Rss
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Feed(Manager *manager, Folder *parent, const QString &url);
|
||||
Feed(const QString &url, Manager *manager);
|
||||
~Feed();
|
||||
|
||||
Folder *parent() const;
|
||||
void setParent(Folder *parent);
|
||||
bool refresh();
|
||||
QString id() const;
|
||||
void removeAllSettings();
|
||||
@ -78,38 +76,35 @@ namespace Rss
|
||||
ArticlePtr getItem(const QString &guid) const;
|
||||
uint count() const;
|
||||
void markAsRead();
|
||||
void markAsDirty(bool dirty = true);
|
||||
uint unreadCount() const;
|
||||
ArticleList articleListByDateDesc() const;
|
||||
const ArticleHash &articleHash() const;
|
||||
ArticleList unreadArticleListByDateDesc() const;
|
||||
void decrementUnreadCount();
|
||||
void recheckRssItemsForDownload();
|
||||
|
||||
private slots:
|
||||
void handleFinishedDownload(const QString &url, const QString &filePath);
|
||||
void handleDownloadFailure(const QString &url, const QString &error);
|
||||
void handleIconDownloadFinished(const QString &url, const QString &filePath);
|
||||
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 handleNewArticle(const QString &feedUrl, const QVariantHash &article);
|
||||
void handleFeedParsingFinished(const QString &feedUrl, const QString &error);
|
||||
void handleArticleStateChanged();
|
||||
void handleParsingFinished(const QString &feedUrl, const QString &error);
|
||||
void handleArticleRead();
|
||||
|
||||
private:
|
||||
QString iconUrl() const;
|
||||
void loadItemsFromDisk();
|
||||
void addArticle(const ArticlePtr &article);
|
||||
void downloadArticleTorrentIfMatching(DownloadRuleList *rules, const ArticlePtr &article);
|
||||
void downloadArticleTorrentIfMatching(const ArticlePtr &article);
|
||||
|
||||
private:
|
||||
Manager *m_manager;
|
||||
ArticleHash m_articles;
|
||||
ArticleList m_articlesByDate; // Articles sorted by date (more recent first)
|
||||
Folder *m_parent;
|
||||
QString m_title;
|
||||
QString m_url;
|
||||
QString m_alias;
|
||||
QString m_icon;
|
||||
QString m_iconUrl;
|
||||
uint m_unreadCount;
|
||||
bool m_dirty;
|
||||
bool m_inErrorState;
|
||||
|
@ -36,11 +36,16 @@ using namespace Rss;
|
||||
|
||||
File::~File() {}
|
||||
|
||||
Folder *File::parentFolder() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
QStringList File::pathHierarchy() const
|
||||
{
|
||||
QStringList path;
|
||||
if (parent())
|
||||
path << parent()->pathHierarchy();
|
||||
if (m_parent)
|
||||
path << m_parent->pathHierarchy();
|
||||
path << id();
|
||||
return path;
|
||||
}
|
||||
|
@ -55,25 +55,27 @@ namespace Rss
|
||||
public:
|
||||
virtual ~File();
|
||||
|
||||
virtual uint unreadCount() const = 0;
|
||||
virtual QString displayName() const = 0;
|
||||
virtual QString id() const = 0;
|
||||
virtual QString displayName() const = 0;
|
||||
virtual uint unreadCount() 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 unreadArticleListByDateDesc() const = 0;
|
||||
|
||||
virtual void rename(const QString &newName) = 0;
|
||||
virtual void markAsRead() = 0;
|
||||
virtual bool refresh() = 0;
|
||||
virtual void removeAllSettings() = 0;
|
||||
virtual void saveItemsToDisk() = 0;
|
||||
virtual void recheckRssItemsForDownload() = 0;
|
||||
|
||||
Folder *parentFolder() const;
|
||||
QStringList pathHierarchy() const;
|
||||
|
||||
protected:
|
||||
uint m_unreadCount;
|
||||
friend class Folder;
|
||||
|
||||
Folder *m_parent = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -40,24 +40,11 @@
|
||||
|
||||
using namespace Rss;
|
||||
|
||||
Folder::Folder(Folder *parent, const QString &name)
|
||||
: m_parent(parent)
|
||||
, m_name(name)
|
||||
Folder::Folder(const QString &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 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
|
||||
bool Folder::refresh()
|
||||
{
|
||||
@ -176,7 +138,8 @@ void Folder::rename(const QString &newName)
|
||||
Q_ASSERT(!m_parent->hasChild(newName));
|
||||
if (!m_parent->hasChild(newName)) {
|
||||
// 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
|
||||
m_name = newName;
|
||||
}
|
||||
@ -224,20 +187,17 @@ QHash<QString, FeedPtr> Folder::getAllFeedsAsHash() const
|
||||
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(feed->url()));
|
||||
m_children[feed->url()] = 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));
|
||||
}
|
||||
Q_ASSERT(!m_children.contains(item->id()));
|
||||
if (!m_children.contains(item->id())) {
|
||||
m_children[item->id()] = item;
|
||||
// Update parent
|
||||
item->setParent(this);
|
||||
item->m_parent = this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Folder::removeAllItems()
|
||||
@ -245,6 +205,11 @@ void Folder::removeAllItems()
|
||||
m_children.clear();
|
||||
}
|
||||
|
||||
FilePtr Folder::child(const QString &childId)
|
||||
{
|
||||
return m_children.value(childId);
|
||||
}
|
||||
|
||||
void Folder::removeAllSettings()
|
||||
{
|
||||
FileHash::ConstIterator it = m_children.begin();
|
||||
@ -274,13 +239,6 @@ bool Folder::hasChild(const QString &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)
|
||||
{
|
||||
return m_children.take(childId);
|
||||
|
@ -48,19 +48,12 @@ namespace Rss
|
||||
typedef QSharedPointer<Folder> FolderPtr;
|
||||
typedef QList<FeedPtr> FeedList;
|
||||
|
||||
class Folder: public QObject, public File
|
||||
class Folder: public File
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Folder(Folder *parent = 0, const QString &name = QString());
|
||||
~Folder();
|
||||
explicit Folder(const QString &name = QString());
|
||||
|
||||
Folder *parent() const;
|
||||
void setParent(Folder *parent);
|
||||
uint unreadCount() const;
|
||||
FeedPtr addStream(Manager *manager, const QString &url);
|
||||
FolderPtr addFolder(const QString &name);
|
||||
uint getNbFeeds() const;
|
||||
FileList getContent() const;
|
||||
FeedList getAllFeeds() const;
|
||||
@ -71,22 +64,20 @@ namespace Rss
|
||||
bool hasChild(const QString &childId);
|
||||
ArticleList articleListByDateDesc() 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 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:
|
||||
Folder *m_parent;
|
||||
QString m_name;
|
||||
FileHash m_children;
|
||||
};
|
||||
|
@ -33,19 +33,23 @@
|
||||
|
||||
#include "base/logger.h"
|
||||
#include "base/preferences.h"
|
||||
#include "private/rssparser.h"
|
||||
#include "rssfolder.h"
|
||||
#include "rssfeed.h"
|
||||
#include "rssarticle.h"
|
||||
#include "rssdownloadrulelist.h"
|
||||
#include "rssparser.h"
|
||||
#include "rssmanager.h"
|
||||
|
||||
static const int MSECS_PER_MIN = 60000;
|
||||
|
||||
using namespace Rss;
|
||||
using namespace Rss::Private;
|
||||
|
||||
Manager::Manager()
|
||||
: m_downloadRules(new DownloadRuleList)
|
||||
Manager::Manager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_downloadRules(new DownloadRuleList)
|
||||
, m_rssParser(new Parser(this))
|
||||
, m_rootFolder(new Folder)
|
||||
{
|
||||
connect(&m_refreshTimer, SIGNAL(timeout()), SLOT(refresh()));
|
||||
m_refreshInterval = Preferences::instance()->getRSSRefreshInterval();
|
||||
@ -57,16 +61,12 @@ Manager::~Manager()
|
||||
qDebug("Deleting RSSManager...");
|
||||
delete m_downloadRules;
|
||||
delete m_rssParser;
|
||||
saveItemsToDisk();
|
||||
m_rootFolder->saveItemsToDisk();
|
||||
saveStreamList();
|
||||
m_rootFolder.clear();
|
||||
qDebug("RSSManager deleted");
|
||||
}
|
||||
|
||||
Parser *Manager::rssParser() const
|
||||
{
|
||||
return m_rssParser;
|
||||
}
|
||||
|
||||
void Manager::updateRefreshInterval(uint val)
|
||||
{
|
||||
if (m_refreshInterval != val) {
|
||||
@ -95,14 +95,22 @@ void Manager::loadStreamList()
|
||||
const QString feedUrl = path.takeLast();
|
||||
qDebug() << "Feed URL:" << feedUrl;
|
||||
// Create feed path (if it does not exists)
|
||||
Folder *feedParent = this;
|
||||
FolderPtr feedParent = m_rootFolder;
|
||||
foreach (const QString &folderName, path) {
|
||||
if (!feedParent->hasChild(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
|
||||
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];
|
||||
if (!alias.isEmpty())
|
||||
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)
|
||||
{
|
||||
Folder *srcFolder = file->parent();
|
||||
Folder *srcFolder = file->parentFolder();
|
||||
if (destinationFolder != srcFolder) {
|
||||
// Remove reference in old folder
|
||||
srcFolder->takeChild(file->id());
|
||||
@ -144,7 +152,7 @@ void Manager::saveStreamList() const
|
||||
{
|
||||
QStringList streamsUrl;
|
||||
QStringList aliases;
|
||||
FeedList streams = getAllFeeds();
|
||||
FeedList streams = m_rootFolder->getAllFeeds();
|
||||
foreach (const FeedPtr &stream, streams) {
|
||||
// This backslash has nothing to do with path handling
|
||||
QString streamPath = stream->pathHierarchy().join("\\");
|
||||
@ -164,3 +172,18 @@ DownloadRuleList *Manager::downloadRules() const
|
||||
Q_ASSERT(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();
|
||||
}
|
||||
|
@ -32,31 +32,44 @@
|
||||
#ifndef RSSMANAGER_H
|
||||
#define RSSMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "rssfolder.h"
|
||||
|
||||
namespace Rss
|
||||
{
|
||||
class DownloadRuleList;
|
||||
class Parser;
|
||||
class File;
|
||||
class Folder;
|
||||
class Feed;
|
||||
class Manager;
|
||||
|
||||
typedef QSharedPointer<File> FilePtr;
|
||||
typedef QSharedPointer<Folder> FolderPtr;
|
||||
typedef QSharedPointer<Feed> FeedPtr;
|
||||
|
||||
namespace Private
|
||||
{
|
||||
class Parser;
|
||||
}
|
||||
|
||||
typedef QSharedPointer<Manager> ManagerPtr;
|
||||
|
||||
class Manager: public Folder
|
||||
class Manager: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Manager();
|
||||
explicit Manager(QObject *parent = 0);
|
||||
~Manager();
|
||||
|
||||
Parser *rssParser() const;
|
||||
DownloadRuleList *downloadRules() const;
|
||||
FolderPtr rootFolder() const;
|
||||
|
||||
Private::Parser *rssParser() const;
|
||||
|
||||
public slots:
|
||||
void refresh();
|
||||
void loadStreamList();
|
||||
void saveStreamList() const;
|
||||
void forwardFeedContentChanged(const QString &url);
|
||||
@ -74,7 +87,8 @@ namespace Rss
|
||||
QTimer m_refreshTimer;
|
||||
uint m_refreshInterval;
|
||||
DownloadRuleList *m_downloadRules;
|
||||
Parser *m_rssParser;
|
||||
Private::Parser *m_rssParser;
|
||||
FolderPtr m_rootFolder;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "base/rss/rssdownloadrulelist.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/rss/rssmanager.h"
|
||||
#include "base/rss/rssfolder.h"
|
||||
#include "base/rss/rssfeed.h"
|
||||
#include "guiiconprovider.h"
|
||||
#include "autoexpandabledialog.h"
|
||||
@ -524,7 +525,7 @@ void AutomatedRssDownloader::updateMatchingArticles()
|
||||
Rss::ManagerPtr manager = m_manager.toStrongRef();
|
||||
if (!manager)
|
||||
return;
|
||||
const QHash<QString, Rss::FeedPtr> all_feeds = manager->getAllFeedsAsHash();
|
||||
const QHash<QString, Rss::FeedPtr> all_feeds = manager->rootFolder()->getAllFeedsAsHash();
|
||||
|
||||
saveEditedRule();
|
||||
foreach (const QListWidgetItem *rule_item, ui->listRules->selectedItems()) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
*/
|
||||
|
||||
#include "base/rss/rssmanager.h"
|
||||
#include "base/rss/rssfolder.h"
|
||||
#include "base/rss/rssfeed.h"
|
||||
#include "guiiconprovider.h"
|
||||
#include "feedlistwidget.h"
|
||||
@ -40,9 +41,9 @@ FeedListWidget::FeedListWidget(QWidget *parent, const Rss::ManagerPtr& rssmanage
|
||||
setColumnCount(1);
|
||||
headerItem()->setText(0, tr("RSS feeds"));
|
||||
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"));
|
||||
itemAdded(m_unreadStickyItem, rssmanager);
|
||||
itemAdded(m_unreadStickyItem, rssmanager->rootFolder());
|
||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(updateCurrentFeed(QTreeWidgetItem*)));
|
||||
setCurrentItem(m_unreadStickyItem);
|
||||
}
|
||||
@ -202,7 +203,7 @@ void FeedListWidget::dropEvent(QDropEvent *event) {
|
||||
dest_folder = qSharedPointerCast<Rss::Folder>(getRSSItem(dest_folder_item));
|
||||
folders_altered << dest_folder_item;
|
||||
} else {
|
||||
dest_folder = m_rssManager;
|
||||
dest_folder = m_rssManager->rootFolder();
|
||||
}
|
||||
QList<QTreeWidgetItem *> src_items = selectedItems();
|
||||
// Check if there is not going to overwrite another file
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "base/rss/rssmanager.h"
|
||||
#include "base/rss/rssfolder.h"
|
||||
#include "base/rss/rssarticle.h"
|
||||
#include "base/rss/rssparser.h"
|
||||
#include "base/rss/rssfeed.h"
|
||||
#include "automatedrssdownloader.h"
|
||||
#include "guiiconprovider.h"
|
||||
@ -79,7 +78,7 @@ void RSSImp::displayRSSListMenu(const QPoint& pos)
|
||||
myRSSListMenu.addAction(actionMark_items_read);
|
||||
myRSSListMenu.addSeparator();
|
||||
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(actionDelete);
|
||||
myRSSListMenu.addSeparator();
|
||||
@ -167,14 +166,15 @@ void RSSImp::askNewFolder()
|
||||
Q_ASSERT(rss_parent);
|
||||
}
|
||||
else {
|
||||
rss_parent = m_rssManager;
|
||||
rss_parent = m_rssManager->rootFolder();
|
||||
}
|
||||
bool 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;
|
||||
|
||||
Rss::FolderPtr newFolder = rss_parent->addFolder(new_name);
|
||||
Rss::FolderPtr newFolder(new Rss::Folder(new_name));
|
||||
rss_parent->addFile(newFolder);
|
||||
QTreeWidgetItem* folderItem = createFolderListItem(newFolder);
|
||||
if (parent_item)
|
||||
parent_item->addChild(folderItem);
|
||||
@ -207,7 +207,7 @@ void RSSImp::on_newFeedButton_clicked()
|
||||
if (parent_item)
|
||||
rss_parent = qSharedPointerCast<Rss::Folder>(m_feedList->getRSSItem(parent_item));
|
||||
else
|
||||
rss_parent = m_rssManager;
|
||||
rss_parent = m_rssManager->rootFolder();
|
||||
// Ask for feed URL
|
||||
bool ok;
|
||||
QString clip_txt = qApp->clipboard()->text();
|
||||
@ -229,7 +229,9 @@ void RSSImp::on_newFeedButton_clicked()
|
||||
QMessageBox::Ok);
|
||||
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
|
||||
QTreeWidgetItem* item = createFolderListItem(stream);
|
||||
if (parent_item)
|
||||
@ -265,17 +267,13 @@ void RSSImp::deleteSelectedItems()
|
||||
// Notify TreeWidget
|
||||
m_feedList->itemAboutToBeRemoved(item);
|
||||
// Actually delete the item
|
||||
rss_item->parent()->removeChild(rss_item->id());
|
||||
rss_item->parentFolder()->removeChild(rss_item->id());
|
||||
delete item;
|
||||
// Update parents count
|
||||
while (parent && parent != m_feedList->invisibleRootItem()) {
|
||||
while (parent && (parent != m_feedList->invisibleRootItem())) {
|
||||
updateItemInfos(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();
|
||||
// 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);
|
||||
// Check if name is already taken
|
||||
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."));
|
||||
ok = false;
|
||||
}
|
||||
@ -489,7 +487,7 @@ void RSSImp::fillFeedsList(QTreeWidgetItem* parent, const Rss::FolderPtr& rss_pa
|
||||
if (parent)
|
||||
children = rss_parent->getContent();
|
||||
else
|
||||
children = m_rssManager->getContent();
|
||||
children = m_rssManager->rootFolder()->getContent();
|
||||
foreach (const Rss::FilePtr& rssFile, children) {
|
||||
QTreeWidgetItem* item = createFolderListItem(rssFile);
|
||||
Q_ASSERT(item);
|
||||
@ -546,7 +544,7 @@ void RSSImp::populateArticleList(QTreeWidgetItem* item)
|
||||
|
||||
qDebug("Getting the list of news");
|
||||
Rss::ArticleList articles;
|
||||
if (rss_item == m_rssManager)
|
||||
if (rss_item == m_rssManager->rootFolder())
|
||||
articles = rss_item->unreadArticleListByDateDesc();
|
||||
else
|
||||
articles = rss_item->articleListByDateDesc();
|
||||
@ -655,7 +653,7 @@ void RSSImp::updateItemInfos(QTreeWidgetItem *item)
|
||||
return;
|
||||
|
||||
QString name;
|
||||
if (rss_item == m_rssManager) {
|
||||
if (rss_item == m_rssManager->rootFolder()) {
|
||||
name = tr("Unread");
|
||||
emit updateRSSCount(rss_item->unreadCount());
|
||||
}
|
||||
@ -799,7 +797,7 @@ void RSSImp::on_rssDownloaderBtn_clicked()
|
||||
AutomatedRssDownloader dlg(m_rssManager, this);
|
||||
dlg.exec();
|
||||
if (dlg.isRssDownloaderEnabled()) {
|
||||
m_rssManager->recheckRssItemsForDownload();
|
||||
m_rssManager->rootFolder()->recheckRssItemsForDownload();
|
||||
refreshAllFeeds();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user