From c232a2eb4cba8461fe9bdf6f55d69816c8e77ae5 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Thu, 17 Dec 2020 14:23:56 +0100 Subject: [PATCH] Huge changes for #325. --- src/librssguard/core/feeddownloader.cpp | 40 ++++++- src/librssguard/core/feeddownloader.h | 8 +- src/librssguard/miscellaneous/feedreader.cpp | 100 +++++++++++------- src/librssguard/miscellaneous/feedreader.h | 11 +- .../services/abstract/cacheforserviceroot.h | 4 +- .../services/abstract/serviceroot.cpp | 4 + .../services/abstract/serviceroot.h | 4 +- .../services/gmail/gmailserviceroot.cpp | 6 +- .../services/gmail/gmailserviceroot.h | 2 +- .../inoreader/inoreaderserviceroot.cpp | 12 ++- .../services/inoreader/inoreaderserviceroot.h | 2 +- .../services/owncloud/owncloudserviceroot.cpp | 6 +- .../services/owncloud/owncloudserviceroot.h | 2 +- .../services/tt-rss/ttrssserviceroot.cpp | 6 +- .../services/tt-rss/ttrssserviceroot.h | 2 +- 15 files changed, 144 insertions(+), 65 deletions(-) diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index f93e7eeca..fb41ac7bd 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -3,6 +3,7 @@ #include "core/feeddownloader.h" #include "3rd-party/boolinq/boolinq.h" +#include "core/feedsmodel.h" #include "core/messagefilter.h" #include "definitions/definitions.h" #include "exceptions/filteringexception.h" @@ -20,7 +21,7 @@ #include FeedDownloader::FeedDownloader() - : QObject(), m_mutex(new QMutex()), m_feedsUpdated(0), m_feedsOriginalCount(0) { + : QObject(), m_isCacheSynchronizationRunning(false), m_stopCacheSynchronization(false), m_mutex(new QMutex()), m_feedsUpdated(0), m_feedsOriginalCount(0) { qRegisterMetaType("FeedDownloadResults"); } @@ -43,7 +44,14 @@ void FeedDownloader::updateAvailableFeeds() { qDebugNN << LOGSEC_FEEDDOWNLOADER << "Saving cache for feed with DB ID '" << feed->id() << "' and title '" << feed->title() << "'."; - cache->saveAllCachedData(false); + cache->saveAllCachedData(); + } + + if (m_stopCacheSynchronization) { + qWarningNN << LOGSEC_FEEDDOWNLOADER << "Aborting cache synchronization."; + + m_stopCacheSynchronization = false; + break; } } @@ -52,6 +60,28 @@ void FeedDownloader::updateAvailableFeeds() { } } +void FeedDownloader::synchronizeAccountCaches(const QList& caches) { + m_isCacheSynchronizationRunning = true; + + for (CacheForServiceRoot* cache : caches) { + qDebugNN << LOGSEC_FEEDDOWNLOADER + << "Synchronizing cache back to server on thread" << QUOTE_W_SPACE_DOT(QThread::currentThreadId()); + cache->saveAllCachedData(); + + if (m_stopCacheSynchronization) { + qWarningNN << LOGSEC_FEEDDOWNLOADER << "Aborting cache synchronization."; + + m_stopCacheSynchronization = false; + break; + } + } + + qDebugNN << LOGSEC_FEEDDOWNLOADER << "All caches synchronized."; + emit cachesSynchronized(); + + m_isCacheSynchronizationRunning = false; +} + void FeedDownloader::updateFeeds(const QList& feeds) { QMutexLocker locker(m_mutex); @@ -77,6 +107,7 @@ void FeedDownloader::updateFeeds(const QList& feeds) { } void FeedDownloader::stopRunningUpdate() { + m_stopCacheSynchronization = true; m_feeds.clear(); m_feedsOriginalCount = m_feedsUpdated = 0; } @@ -291,6 +322,11 @@ void FeedDownloader::finalizeUpdate() { emit updateFinished(m_results); } +bool FeedDownloader::isCacheSynchronizationRunning() const +{ + return m_isCacheSynchronizationRunning; +} + QString FeedDownloadResults::overview(int how_many_feeds) const { QStringList result; diff --git a/src/librssguard/core/feeddownloader.h b/src/librssguard/core/feeddownloader.h index ab61fe7d0..bf38e6beb 100644 --- a/src/librssguard/core/feeddownloader.h +++ b/src/librssguard/core/feeddownloader.h @@ -8,6 +8,7 @@ #include #include "core/message.h" +#include "services/abstract/cacheforserviceroot.h" #include "services/abstract/feed.h" class MessageFilter; @@ -39,12 +40,15 @@ class FeedDownloader : public QObject { virtual ~FeedDownloader(); bool isUpdateRunning() const; + bool isCacheSynchronizationRunning() const; public slots: + void synchronizeAccountCaches(const QList& caches); void updateFeeds(const QList& feeds); void stopRunningUpdate(); signals: + void cachesSynchronized(); void updateStarted(); void updateFinished(FeedDownloadResults updated_feeds); void updateProgress(const Feed* feed, int current, int total); @@ -54,7 +58,9 @@ class FeedDownloader : public QObject { void updateAvailableFeeds(); void finalizeUpdate(); - QList m_feeds; + bool m_isCacheSynchronizationRunning; + bool m_stopCacheSynchronization; + QList m_feeds = {}; QMutex* m_mutex; FeedDownloadResults m_results; int m_feedsUpdated; diff --git a/src/librssguard/miscellaneous/feedreader.cpp b/src/librssguard/miscellaneous/feedreader.cpp index a2efb6903..335be49a9 100644 --- a/src/librssguard/miscellaneous/feedreader.cpp +++ b/src/librssguard/miscellaneous/feedreader.cpp @@ -2,6 +2,7 @@ #include "miscellaneous/feedreader.h" +#include "3rd-party/boolinq/boolinq.h" #include "core/feeddownloader.h" #include "core/feedsmodel.h" #include "core/feedsproxymodel.h" @@ -33,7 +34,6 @@ FeedReader::FeedReader(QObject* parent) connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate); updateAutoUpdateStatus(); - asyncCacheSaveFinished(); if (qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool()) { qDebugNN << LOGSEC_CORE @@ -66,11 +66,28 @@ QList FeedReader::feedServices() { void FeedReader::updateFeeds(const QList& feeds) { if (!qApp->feedUpdateLock()->tryLock()) { qApp->showGuiMessage(tr("Cannot update all items"), - tr("You cannot update all items because another critical operation is ongoing."), + tr("You cannot update items " + "because another critical operation is ongoing."), QSystemTrayIcon::MessageIcon::Warning, qApp->mainFormWidget(), true); return; } + initializeFeedDownloader(); + + QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", + Qt::ConnectionType::QueuedConnection, + Q_ARG(QList, feeds)); +} + +void FeedReader::synchronizeMessageData(const QList& caches) { + initializeFeedDownloader(); + + QMetaObject::invokeMethod(m_feedDownloader, "synchronizeAccountCaches", + Qt::ConnectionType::QueuedConnection, + Q_ARG(QList, caches)); +} + +void FeedReader::initializeFeedDownloader() { if (m_feedDownloader == nullptr) { qDebugNN << LOGSEC_CORE << "Creating FeedDownloader singleton."; @@ -79,6 +96,7 @@ void FeedReader::updateFeeds(const QList& feeds) { // Downloader setup. qRegisterMetaType>("QList"); + qRegisterMetaType>("QList"); m_feedDownloader->moveToThread(m_feedDownloaderThread); @@ -91,10 +109,6 @@ void FeedReader::updateFeeds(const QList& feeds) { m_feedDownloaderThread->start(); } - - QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", - Qt::ConnectionType::QueuedConnection, - Q_ARG(QList, feeds)); } void FeedReader::showMessageFiltersManager() { @@ -230,16 +244,39 @@ MessagesModel* FeedReader::messagesModel() const { } void FeedReader::executeNextAutoUpdate() { - if (qApp->mainFormWidget()->isActiveWindow() && m_globalAutoUpdateOnlyUnfocused) { + bool disable_update_with_window = qApp->mainFormWidget()->isActiveWindow() && m_globalAutoUpdateOnlyUnfocused; + auto roots = qApp->feedReader()->feedsModel()->serviceRoots(); + std::list full_caches = boolinq::from(roots) + .select([](ServiceRoot* root) -> CacheForServiceRoot* { + auto* cache = root->toCache(); + + if (cache != nullptr) { + return cache; + } + else { + return nullptr; + } + }) + .where([](CacheForServiceRoot* cache) { + return !cache->isEmpty(); + }).toStdList(); + + // Skip this round of auto-updating, but only if user disabled it when main window is active + // and there are no caches to synchronize. + if (disable_update_with_window && full_caches.empty()) { qDebugNN << LOGSEC_CORE - << "Delaying scheduled feed auto-update for one minute since window is focused and updates while focused are disabled by the user."; + << "Delaying scheduled feed auto-update for one minute since window " + << "is focused and updates while focused are disabled by the " + << "user and all account caches are empty."; // Cannot update, quit. return; } if (!qApp->feedUpdateLock()->tryLock()) { - qDebugNN << LOGSEC_CORE << "Delaying scheduled feed auto-updates for one minute due to another running update."; + qDebugNN << LOGSEC_CORE + << "Delaying scheduled feed auto-updates and message state synchronization for " + << "one minute due to another running update."; // Cannot update, quit. return; @@ -253,51 +290,37 @@ void FeedReader::executeNextAutoUpdate() { } qDebugNN << LOGSEC_CORE - << "Starting auto-update event, pass " - << m_globalAutoUpdateRemainingInterval << "/" << m_globalAutoUpdateInitialInterval << "."; + << "Starting auto-update event, remaining " + << m_globalAutoUpdateRemainingInterval << "minutes out of " + << m_globalAutoUpdateInitialInterval << "total minutes to next global feed update."; + + qApp->feedUpdateLock()->unlock(); + + // Resynchronize caches. + if (!full_caches.empty()) { + QList caches = FROM_STD_LIST(QList, full_caches); + + synchronizeMessageData(caches); + } // Pass needed interval data and lets the model decide which feeds // should be updated in this pass. QList feeds_for_update = m_feedsModel->feedsForScheduledUpdate(m_globalAutoUpdateEnabled && m_globalAutoUpdateRemainingInterval == 0); - qApp->feedUpdateLock()->unlock(); - if (!feeds_for_update.isEmpty()) { // Request update for given feeds. updateFeeds(feeds_for_update); - // NOTE: OSD/bubble informing about performing - // of scheduled update can be shown now. + // NOTE: OSD/bubble informing about performing of scheduled update can be shown now. if (qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::EnableAutoUpdateNotification)).toBool()) { qApp->showGuiMessage(tr("Starting auto-update of some feeds"), tr("I will auto-update %n feed(s).", nullptr, feeds_for_update.size()), - QSystemTrayIcon::Information); + QSystemTrayIcon::MessageIcon::Information); } } } -void FeedReader::checkServicesForAsyncOperations() { - for (ServiceRoot* service : m_feedsModel->serviceRoots()) { - auto cache = dynamic_cast(service); - - if (cache != nullptr) { - cache->saveAllCachedData(); - } - } - - asyncCacheSaveFinished(); -} - -void FeedReader::asyncCacheSaveFinished() { - qDebugNN << LOGSEC_CORE << "I will start next check for cached service data in 60 seconds."; - - QTimer::singleShot(60000, this, [&] { - qDebugNN << LOGSEC_CORE << "Saving cached metadata NOW."; - checkServicesForAsyncOperations(); - }); -} - QList FeedReader::messageFilters() const { return m_messageFilters; } @@ -311,9 +334,10 @@ void FeedReader::quit() { if (m_feedDownloader != nullptr) { m_feedDownloader->stopRunningUpdate(); - if (m_feedDownloader->isUpdateRunning()) { + if (m_feedDownloader->isUpdateRunning() || m_feedDownloader->isCacheSynchronizationRunning()) { QEventLoop loop(this); + connect(m_feedDownloader, &FeedDownloader::cachesSynchronized, &loop, &QEventLoop::quit); connect(m_feedDownloader, &FeedDownloader::updateFinished, &loop, &QEventLoop::quit); loop.exec(); } diff --git a/src/librssguard/miscellaneous/feedreader.h b/src/librssguard/miscellaneous/feedreader.h index a69af13a4..0962e568e 100644 --- a/src/librssguard/miscellaneous/feedreader.h +++ b/src/librssguard/miscellaneous/feedreader.h @@ -7,6 +7,7 @@ #include "core/feeddownloader.h" #include "core/messagefilter.h" +#include "services/abstract/cacheforserviceroot.h" #include "services/abstract/feed.h" #include @@ -36,9 +37,12 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject { FeedsProxyModel* feedsProxyModel() const; MessagesProxyModel* messagesProxyModel() const; - // Schedules given feeds for update. + // Update feeds in extra thread. void updateFeeds(const QList& feeds); + // Push back cached message states back to servers in extra thread. + void synchronizeMessageData(const QList& caches); + void showMessageFiltersManager(); // True if feed update is running right now. @@ -68,14 +72,15 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject { private slots: void executeNextAutoUpdate(); - void checkServicesForAsyncOperations(); - void asyncCacheSaveFinished(); signals: void feedUpdatesStarted(); void feedUpdatesFinished(FeedDownloadResults updated_feeds); void feedUpdatesProgress(const Feed* feed, int current, int total); + private: + void initializeFeedDownloader(); + private: QList m_feedServices; QList m_messageFilters; diff --git a/src/librssguard/services/abstract/cacheforserviceroot.h b/src/librssguard/services/abstract/cacheforserviceroot.h index 02a48fef0..d02e92397 100644 --- a/src/librssguard/services/abstract/cacheforserviceroot.h +++ b/src/librssguard/services/abstract/cacheforserviceroot.h @@ -22,7 +22,7 @@ class CacheForServiceRoot { public: explicit CacheForServiceRoot(); - virtual void saveAllCachedData(bool async = true) = 0; + virtual void saveAllCachedData() = 0; void addLabelsAssignmentsToCache(const QStringList& ids_of_messages, const QString& lbl_custom_id, bool assign); void addLabelsAssignmentsToCache(const QList& ids_of_messages, Label* lbl, bool assign); @@ -31,6 +31,7 @@ class CacheForServiceRoot { void loadCacheFromFile(); void setUniqueId(int unique_id); + bool isEmpty() const; protected: @@ -40,7 +41,6 @@ class CacheForServiceRoot { CacheSnapshot takeMessageCache(); private: - bool isEmpty() const; void clearCache(); void saveCacheToFile(); diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index 5e20b1f4a..91a65dabf 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -672,6 +672,10 @@ bool ServiceRoot::onAfterMessagesRestoredFromBin(RootItem* selected_item, const return true; } +CacheForServiceRoot* ServiceRoot::toCache() const { + return dynamic_cast(const_cast(this)); +} + void ServiceRoot::assembleFeeds(Assignment feeds) { QHash categories = getHashedSubTreeCategories(); diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index d6ffc1753..23c65ad67 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -16,6 +16,7 @@ class LabelsNode; class Label; class QAction; class MessagesModel; +class CacheForServiceRoot; // Car here represents ID (int, primary key) of the item. typedef QList> Assignment; @@ -151,7 +152,8 @@ class ServiceRoot : public RootItem { // NOTE: Keep in sync with ServiceEntryRoot::code(). virtual QString code() const = 0; - // These are not part of "interface". + // These are not part of "interface". + CacheForServiceRoot* toCache() const; public: diff --git a/src/librssguard/services/gmail/gmailserviceroot.cpp b/src/librssguard/services/gmail/gmailserviceroot.cpp index 04454b156..9f9c94af2 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.cpp +++ b/src/librssguard/services/gmail/gmailserviceroot.cpp @@ -205,7 +205,7 @@ QString GmailServiceRoot::additionalTooltip() const { network()->oauth()->tokensExpireIn().toString() : QSL("-")); } -void GmailServiceRoot::saveAllCachedData(bool async) { +void GmailServiceRoot::saveAllCachedData() { auto msg_cache = takeMessageCache(); QMapIterator i(msg_cache.m_cachedStatesRead); @@ -216,7 +216,7 @@ void GmailServiceRoot::saveAllCachedData(bool async) { QStringList ids = i.value(); if (!ids.isEmpty()) { - network()->markMessagesRead(key, ids, async); + network()->markMessagesRead(key, ids, false); } } @@ -235,7 +235,7 @@ void GmailServiceRoot::saveAllCachedData(bool async) { custom_ids.append(msg.m_customId); } - network()->markMessagesStarred(key, custom_ids, async); + network()->markMessagesStarred(key, custom_ids, false); } } } diff --git a/src/librssguard/services/gmail/gmailserviceroot.h b/src/librssguard/services/gmail/gmailserviceroot.h index edba32a3c..6c701a2cd 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.h +++ b/src/librssguard/services/gmail/gmailserviceroot.h @@ -33,7 +33,7 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void start(bool freshly_activated); virtual QString code() const; virtual QString additionalTooltip() const; - virtual void saveAllCachedData(bool async = true); + virtual void saveAllCachedData(); void updateTitle(); diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp index 7259b8736..dfac9708c 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp @@ -14,6 +14,8 @@ #include "services/inoreader/inoreaderfeed.h" #include "services/inoreader/network/inoreadernetworkfactory.h" +#include + InoreaderServiceRoot::InoreaderServiceRoot(InoreaderNetworkFactory* network, RootItem* parent) : ServiceRoot(parent), m_network(network) { if (network == nullptr) { @@ -146,7 +148,7 @@ RootItem* InoreaderServiceRoot::obtainNewTreeForSyncIn() const { } } -void InoreaderServiceRoot::saveAllCachedData(bool async) { +void InoreaderServiceRoot::saveAllCachedData() { auto msg_cache = takeMessageCache(); QMapIterator i(msg_cache.m_cachedStatesRead); @@ -157,7 +159,7 @@ void InoreaderServiceRoot::saveAllCachedData(bool async) { QStringList ids = i.value(); if (!ids.isEmpty()) { - network()->markMessagesRead(key, ids, async); + network()->markMessagesRead(key, ids, false); } } @@ -176,7 +178,7 @@ void InoreaderServiceRoot::saveAllCachedData(bool async) { custom_ids.append(msg.m_customId); } - network()->markMessagesStarred(key, custom_ids, async); + network()->markMessagesStarred(key, custom_ids, false); } } @@ -189,7 +191,7 @@ void InoreaderServiceRoot::saveAllCachedData(bool async) { QStringList messages = k.value(); if (!messages.isEmpty()) { - network()->editLabels(label_custom_id, true, messages, async); + network()->editLabels(label_custom_id, true, messages, false); } } @@ -202,7 +204,7 @@ void InoreaderServiceRoot::saveAllCachedData(bool async) { QStringList messages = l.value(); if (!messages.isEmpty()) { - network()->editLabels(label_custom_id, false, messages, async); + network()->editLabels(label_custom_id, false, messages, false); } } } diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.h b/src/librssguard/services/inoreader/inoreaderserviceroot.h index 91344c70a..d1ff46b59 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.h +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.h @@ -31,7 +31,7 @@ class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void start(bool freshly_activated); virtual QString code() const; virtual QString additionalTooltip() const; - virtual void saveAllCachedData(bool async = true); + virtual void saveAllCachedData(); void updateTitle(); diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.cpp b/src/librssguard/services/owncloud/owncloudserviceroot.cpp index 1b9f276ba..c70620df5 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.cpp +++ b/src/librssguard/services/owncloud/owncloudserviceroot.cpp @@ -80,7 +80,7 @@ OwnCloudNetworkFactory* OwnCloudServiceRoot::network() const { return m_network; } -void OwnCloudServiceRoot::saveAllCachedData(bool async) { +void OwnCloudServiceRoot::saveAllCachedData() { auto msg_cache = takeMessageCache(); QMapIterator i(msg_cache.m_cachedStatesRead); @@ -91,7 +91,7 @@ void OwnCloudServiceRoot::saveAllCachedData(bool async) { QStringList ids = i.value(); if (!ids.isEmpty()) { - network()->markMessagesRead(key, ids, async); + network()->markMessagesRead(key, ids, false); } } @@ -111,7 +111,7 @@ void OwnCloudServiceRoot::saveAllCachedData(bool async) { guid_hashes.append(msg.m_customHash); } - network()->markMessagesStarred(key, feed_ids, guid_hashes, async); + network()->markMessagesStarred(key, feed_ids, guid_hashes, false); } } } diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.h b/src/librssguard/services/owncloud/owncloudserviceroot.h index 548560a95..917e7e205 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.h +++ b/src/librssguard/services/owncloud/owncloudserviceroot.h @@ -27,7 +27,7 @@ class OwnCloudServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual bool supportsCategoryAdding() const; virtual void start(bool freshly_activated); virtual QString code() const; - virtual void saveAllCachedData(bool async = true); + virtual void saveAllCachedData(); OwnCloudNetworkFactory* network() const; diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index 17ae9129e..49df60d80 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -117,7 +117,7 @@ bool TtRssServiceRoot::canBeDeleted() const { return true; } -void TtRssServiceRoot::saveAllCachedData(bool async) { +void TtRssServiceRoot::saveAllCachedData() { auto msg_cache = takeMessageCache(); QMapIterator i(msg_cache.m_cachedStatesRead); @@ -133,7 +133,7 @@ void TtRssServiceRoot::saveAllCachedData(bool async) { key == RootItem::ReadStatus::Unread ? UpdateArticle::Mode::SetToTrue : UpdateArticle::Mode::SetToFalse, - async); + false); if (network()->lastError() != QNetworkReply::NetworkError::NoError || res.hasError()) { addMessageStatesToCache(ids, key); @@ -156,7 +156,7 @@ void TtRssServiceRoot::saveAllCachedData(bool async) { key == RootItem::Importance::Important ? UpdateArticle::Mode::SetToTrue : UpdateArticle::Mode::SetToFalse, - async); + false); if (network()->lastError() != QNetworkReply::NetworkError::NoError || res.hasError()) { addMessageStatesToCache(messages, key); diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.h b/src/librssguard/services/tt-rss/ttrssserviceroot.h index 07f89c647..94f0bdc4d 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.h +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.h @@ -32,7 +32,7 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual bool supportsCategoryAdding() const; virtual void addNewFeed(RootItem* selected_item, const QString& url = QString()); virtual QString additionalTooltip() const; - virtual void saveAllCachedData(bool async = true); + virtual void saveAllCachedData(); // Access to network. TtRssNetworkFactory* network() const;