This commit is contained in:
Martin Rotter 2022-09-15 14:28:48 +02:00
parent 810dd30412
commit 94983a3b41
14 changed files with 150 additions and 134 deletions

View File

@ -2,8 +2,10 @@
<qresource prefix="/">
<file>sql/db_init_mysql.sql</file>
<file>sql/db_update_mysql_1_2.sql</file>
<file>sql/db_update_mysql_2_3.sql</file>
<file>sql/db_init_sqlite.sql</file>
<file>sql/db_update_sqlite_1_2.sql</file>
<file>sql/db_update_sqlite_2_3.sql</file>
</qresource>
</RCC>

View File

@ -40,7 +40,7 @@ CREATE TABLE Feeds (
category INTEGER NOT NULL CHECK (category >= -1), /* Physical category ID, also root feeds contain -1 here. */
source TEXT,
update_type INTEGER NOT NULL CHECK (update_type >= 0),
update_interval INTEGER NOT NULL DEFAULT 15 CHECK (update_interval >= 1),
update_interval INTEGER NOT NULL DEFAULT 900 CHECK (update_interval >= 1),
is_off INTEGER NOT NULL DEFAULT 0 CHECK (is_off >= 0 AND is_off <= 1),
open_articles INTEGER NOT NULL DEFAULT 0 CHECK (open_articles >= 0 AND open_articles <= 1),
account_id INTEGER NOT NULL,

View File

@ -69,6 +69,8 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
m_feedsOriginalCount = m_feeds.size();
m_feedsUpdated = 0;
const QDateTime update_time = QDateTime::currentDateTimeUtc();
if (feeds.isEmpty()) {
qDebugNN << LOGSEC_FEEDDOWNLOADER << "No feeds to update in worker thread, aborting update.";
}
@ -157,6 +159,8 @@ void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
else {
updateOneFeed(n_r, n_f, stated_messages.value(n_r).value(n_f->customId()), tagged_messages.value(n_r));
}
n_f->setLastUpdated(QDateTime::currentDateTimeUtc());
}
}

View File

@ -260,18 +260,8 @@ QList<Feed*> FeedsModel::feedsForScheduledUpdate(bool auto_update_now) {
case Feed::AutoUpdateType::SpecificAutoUpdate:
default:
int remaining_interval = feed->autoUpdateRemainingInterval();
if (--remaining_interval <= 0) {
// Interval of this feed passed, include this feed in the output list
// and reset the interval.
if (feed->lastUpdated().addSecs(feed->autoUpdateInterval()) < QDateTime::currentDateTimeUtc()) {
feeds_for_update.append(feed);
feed->setAutoUpdateRemainingInterval(feed->autoUpdateInitialInterval());
}
else {
// Interval did not pass, set new decremented interval and do NOT
// include this feed in the output list.
feed->setAutoUpdateRemainingInterval(remaining_interval);
}
break;

View File

@ -2068,7 +2068,7 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
q.bindValue(QSL(":category"), new_parent_id);
q.bindValue(QSL(":source"), feed->source());
q.bindValue(QSL(":update_type"), int(feed->autoUpdateType()));
q.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval());
q.bindValue(QSL(":update_interval"), feed->autoUpdateInterval());
q.bindValue(QSL(":account_id"), account_id);
q.bindValue(QSL(":custom_id"), feed->customId());
q.bindValue(QSL(":id"), feed->id());

View File

@ -304,7 +304,7 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
feed->setCreationDate(TextFactory::parseDateTime(query.value(FDS_DB_DCREATED_INDEX).value<qint64>()));
feed->setIcon(qApp->icons()->fromByteArray(query.value(FDS_DB_ICON_INDEX).toByteArray()));
feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(query.value(FDS_DB_UPDATE_TYPE_INDEX).toInt()));
feed->setAutoUpdateInitialInterval(query.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt());
feed->setAutoUpdateInterval(query.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt());
feed->setIsSwitchedOff(query.value(FDS_DB_IS_OFF_INDEX).toBool());
feed->setOpenArticlesDirectly(query.value(FDS_DB_OPEN_ARTICLES_INDEX).toBool());

View File

@ -73,9 +73,9 @@
#define FEEDS_VIEW_COLUMN_COUNT 2
#define DEFAULT_DAYS_TO_DELETE_MSG 14
#define ELLIPSIS_LENGTH 3
#define DEFAULT_AUTO_UPDATE_INTERVAL 15
#define AUTO_UPDATE_INTERVAL 60000
#define STARTUP_UPDATE_DELAY 15.0 // In seconds.
#define DEFAULT_AUTO_UPDATE_INTERVAL 900 // In seconds.
#define AUTO_UPDATE_INTERVAL 10 // In seconds.
#define STARTUP_UPDATE_DELAY 15.0 // In seconds.
#define TIMEZONE_OFFSET_LIMIT 6
#define CHANGE_EVENT_DELAY 250
#define FLAG_ICON_SUBFOLDER "flags"
@ -370,6 +370,7 @@
#endif
#define NONQUOTE_W_SPACE_DOT(x) " " << (x) << "."
#define NONQUOTE_W_SPACE(x) " " << (x) << " "
#define QUOTE_W_SPACE_DOT(x) " '" << (x) << "'."
#define QUOTE_W_SPACE_COMMA(x) " '" << (x) << "',"
#define QUOTE_W_SPACE(x) " '" << (x) << "' "

View File

@ -20,6 +20,7 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages) {
m_ui->setupUi(this);
m_ui->m_spinAutoUpdateInterval->setMode(TimeSpinBox::Mode::MinutesSeconds);
m_ui->m_spinStartupUpdateDelay->setMode(TimeSpinBox::Mode::MinutesSeconds);
initializeMessageDateFormats();

View File

@ -27,25 +27,26 @@
#include <QTimer>
FeedReader::FeedReader(QObject* parent)
: QObject(parent),
m_autoUpdateTimer(new QTimer(this)), m_feedDownloader(nullptr) {
: QObject(parent), m_autoUpdateTimer(new QTimer(this)), m_feedDownloader(nullptr) {
m_feedsModel = new FeedsModel(this);
m_feedsProxyModel = new FeedsProxyModel(m_feedsModel, this);
m_messagesModel = new MessagesModel(this);
m_messagesProxyModel = new MessagesProxyModel(m_messagesModel, this);
connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate);
updateAutoUpdateStatus();
initializeFeedDownloader();
if (qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool()) {
qDebugNN << LOGSEC_CORE
<< "Requesting update for all feeds on application startup.";
qDebugNN << LOGSEC_CORE << "Requesting update for all feeds on application startup.";
QTimer::singleShot(qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateStartupDelay)).toDouble() * 1000,
this,
[this]() {
updateFeeds(m_feedsModel->rootItem()->getSubAutoFetchingEnabledFeeds());
});
updateFeeds(m_feedsModel->rootItem()->getSubAutoFetchingEnabledFeeds());
connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate);
});
}
else {
connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate);
}
}
@ -85,20 +86,22 @@ void FeedReader::updateFeeds(const QList<Feed*>& feeds) {
}
if (!qApp->feedUpdateLock()->tryLock()) {
qApp->showGuiMessage(Notification::Event::GeneralEvent, {
tr("Cannot fetch articles at this point"),
tr("You cannot fetch new articles now because another critical operation is ongoing."),
QSystemTrayIcon::MessageIcon::Warning });
qApp->showGuiMessage(Notification::Event::GeneralEvent,
{tr("Cannot fetch articles at this point"),
tr("You cannot fetch new articles now because another critical operation is ongoing."),
QSystemTrayIcon::MessageIcon::Warning});
return;
}
QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds",
QMetaObject::invokeMethod(m_feedDownloader,
"updateFeeds",
Qt::ConnectionType::QueuedConnection,
Q_ARG(QList<Feed*>, my_feeds));
}
void FeedReader::synchronizeMessageData(const QList<CacheForServiceRoot*>& caches) {
QMetaObject::invokeMethod(m_feedDownloader, "synchronizeAccountCaches",
QMetaObject::invokeMethod(m_feedDownloader,
"synchronizeAccountCaches",
Qt::ConnectionType::QueuedConnection,
Q_ARG(QList<CacheForServiceRoot*>, caches),
Q_ARG(bool, true));
@ -128,6 +131,10 @@ void FeedReader::initializeFeedDownloader() {
}
}
QDateTime FeedReader::lastAutoUpdate() const {
return m_lastAutoUpdate;
}
void FeedReader::showMessageFiltersManager() {
FormMessageFiltersManager manager(qApp->feedReader(),
qApp->feedReader()->feedsModel()->serviceRoots(),
@ -141,21 +148,24 @@ void FeedReader::showMessageFiltersManager() {
void FeedReader::updateAutoUpdateStatus() {
// Restore global intervals.
// NOTE: Specific per-feed interval are left intact.
m_globalAutoUpdateInitialInterval = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt();
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval;
m_globalAutoUpdateInterval = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt();
if (m_lastAutoUpdate.isNull()) {
m_lastAutoUpdate = QDateTime::currentDateTimeUtc();
}
m_globalAutoUpdateEnabled = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateEnabled)).toBool();
m_globalAutoUpdateOnlyUnfocused = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateOnlyUnfocused)).toBool();
m_globalAutoUpdateOnlyUnfocused =
qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateOnlyUnfocused)).toBool();
// Start global auto-update timer if it is not running yet.
// NOTE: The timer must run even if global auto-update
// is not enabled because user can still enable auto-update
// for individual feeds.
if (!m_autoUpdateTimer->isActive()) {
m_autoUpdateTimer->setInterval(AUTO_UPDATE_INTERVAL);
m_autoUpdateTimer->setInterval(AUTO_UPDATE_INTERVAL * 1000);
m_autoUpdateTimer->start();
qDebugNN << LOGSEC_CORE << "Auto-download timer started with interval "
<< m_autoUpdateTimer->interval()
<< " ms.";
qDebugNN << LOGSEC_CORE << "Auto-download timer started with interval " << m_autoUpdateTimer->interval() << " ms.";
}
else {
qDebugNN << LOGSEC_CORE << "Auto-download timer is already running.";
@ -166,19 +176,16 @@ bool FeedReader::autoUpdateEnabled() const {
return m_globalAutoUpdateEnabled;
}
int FeedReader::autoUpdateRemainingInterval() const {
return m_globalAutoUpdateRemainingInterval;
}
int FeedReader::autoUpdateInitialInterval() const {
return m_globalAutoUpdateInitialInterval;
int FeedReader::autoUpdateInterval() const {
return m_globalAutoUpdateInterval;
}
void FeedReader::loadSavedMessageFilters() {
// Load all message filters from database.
// All plugin services will hook active filters to
// all feeds.
m_messageFilters = DatabaseQueries::getMessageFilters(qApp->database()->driver()->connection(metaObject()->className()));
m_messageFilters =
DatabaseQueries::getMessageFilters(qApp->database()->driver()->connection(metaObject()->className()));
for (auto* filter : qAsConst(m_messageFilters)) {
filter->setParent(this);
@ -186,7 +193,8 @@ void FeedReader::loadSavedMessageFilters() {
}
MessageFilter* FeedReader::addMessageFilter(const QString& title, const QString& script) {
auto* fltr = DatabaseQueries::addMessageFilter(qApp->database()->driver()->connection(metaObject()->className()), title, script);
auto* fltr =
DatabaseQueries::addMessageFilter(qApp->database()->driver()->connection(metaObject()->className()), title, script);
m_messageFilters.append(fltr);
return fltr;
@ -203,7 +211,8 @@ void FeedReader::removeMessageFilter(MessageFilter* filter) {
}
// Remove from DB.
DatabaseQueries::removeMessageFilterAssignments(qApp->database()->driver()->connection(metaObject()->className()), filter->id());
DatabaseQueries::removeMessageFilterAssignments(qApp->database()->driver()->connection(metaObject()->className()),
filter->id());
DatabaseQueries::removeMessageFilter(qApp->database()->driver()->connection(metaObject()->className()), filter->id());
// Free from memory as last step.
@ -264,25 +273,25 @@ void FeedReader::executeNextAutoUpdate() {
bool disable_update_with_window = qApp->mainFormWidget()->isActiveWindow() && m_globalAutoUpdateOnlyUnfocused;
auto roots = qApp->feedReader()->feedsModel()->serviceRoots();
std::list<CacheForServiceRoot*> full_caches = boolinq::from(roots)
.select([](ServiceRoot* root) -> CacheForServiceRoot* {
auto* cache = root->toCache();
.select([](ServiceRoot* root) -> CacheForServiceRoot* {
auto* cache = root->toCache();
if (cache != nullptr) {
return cache;
}
else {
return nullptr;
}
})
.where([](CacheForServiceRoot* cache) {
return cache != nullptr && !cache->isEmpty();
}).toStdList();
if (cache != nullptr) {
return cache;
}
else {
return nullptr;
}
})
.where([](CacheForServiceRoot* cache) {
return cache != nullptr && !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-download for one minute since window "
qDebugNN << LOGSEC_CORE << "Delaying scheduled feed auto-download for some time since window "
<< "is focused and updates while focused are disabled by the "
<< "user and all account caches are empty.";
@ -291,26 +300,13 @@ void FeedReader::executeNextAutoUpdate() {
}
if (!qApp->feedUpdateLock()->tryLock()) {
qDebugNN << LOGSEC_CORE
<< "Delaying scheduled feed auto-downloads and message state synchronization for "
qDebugNN << LOGSEC_CORE << "Delaying scheduled feed auto-downloads and message state synchronization for "
<< "one minute due to another running update.";
// Cannot update, quit.
return;
}
// If global auto-update is enabled and its interval counter reached zero,
// then we need to restore it.
if (m_globalAutoUpdateEnabled && --m_globalAutoUpdateRemainingInterval < 0) {
// We should start next auto-update interval.
m_globalAutoUpdateRemainingInterval = m_globalAutoUpdateInitialInterval - 1;
}
qDebugNN << LOGSEC_CORE
<< "Starting auto-download event, remaining "
<< m_globalAutoUpdateRemainingInterval << " minutes out of "
<< m_globalAutoUpdateInitialInterval << " total minutes to next global feed update.";
qApp->feedUpdateLock()->unlock();
// Resynchronize caches.
@ -322,18 +318,29 @@ void FeedReader::executeNextAutoUpdate() {
// Pass needed interval data and lets the model decide which feeds
// should be updated in this pass.
QList<Feed*> feeds_for_update = m_feedsModel->feedsForScheduledUpdate(m_globalAutoUpdateEnabled &&
m_globalAutoUpdateRemainingInterval == 0);
QDateTime current_time = QDateTime::currentDateTimeUtc();
bool auto_update_now =
m_globalAutoUpdateEnabled && m_lastAutoUpdate.addSecs(m_globalAutoUpdateInterval) < current_time;
if (auto_update_now) {
qDebugNN << LOGSEC_CORE << "Now it's time to auto-fetch articles because last auto-fetch was on"
<< QUOTE_W_SPACE(m_lastAutoUpdate) << "and next should be in"
<< NONQUOTE_W_SPACE(m_globalAutoUpdateInterval) << "seconds.";
m_lastAutoUpdate = current_time;
}
QList<Feed*> feeds_for_update = m_feedsModel->feedsForScheduledUpdate(auto_update_now);
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.
qApp->showGuiMessage(Notification::Event::ArticlesFetchingStarted, {
tr("Starting auto-download of some feeds' articles"),
tr("I will auto-download new articles for %n feed(s).", nullptr, feeds_for_update.size()),
QSystemTrayIcon::MessageIcon::Information });
qApp->showGuiMessage(Notification::Event::ArticlesFetchingStarted,
{tr("Starting auto-download of some feeds' articles"),
tr("I will auto-download new articles for %n feed(s).", nullptr, feeds_for_update.size()),
QSystemTrayIcon::MessageIcon::Information});
}
}

View File

@ -21,7 +21,7 @@ class QTimer;
class QThread;
class RSSGUARD_DLLSPEC FeedReader : public QObject {
Q_OBJECT
Q_OBJECT
public:
explicit FeedReader(QObject* parent = nullptr);
@ -53,8 +53,8 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject {
void updateAutoUpdateStatus();
bool autoUpdateEnabled() const;
int autoUpdateRemainingInterval() const;
int autoUpdateInitialInterval() const;
int autoUpdateInterval() const;
QDateTime lastAutoUpdate() const;
void loadSavedMessageFilters();
QList<MessageFilter*> messageFilters() const;
@ -93,8 +93,8 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject {
QTimer* m_autoUpdateTimer;
bool m_globalAutoUpdateEnabled{};
bool m_globalAutoUpdateOnlyUnfocused{};
int m_globalAutoUpdateInitialInterval{};
int m_globalAutoUpdateRemainingInterval{};
int m_globalAutoUpdateInterval{}; // In seconds.
QDateTime m_lastAutoUpdate;
QThread* m_feedDownloaderThread;
FeedDownloader* m_feedDownloader;
};

View File

@ -21,8 +21,8 @@
Feed::Feed(RootItem* parent)
: RootItem(parent), m_source(QString()), m_status(Status::Normal), m_statusString(QString()),
m_autoUpdateType(AutoUpdateType::DefaultAutoUpdate), m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL),
m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_isSwitchedOff(false), m_openArticlesDirectly(false),
m_autoUpdateType(AutoUpdateType::DefaultAutoUpdate), m_autoUpdateInterval(DEFAULT_AUTO_UPDATE_INTERVAL),
m_lastUpdated(QDateTime::currentDateTimeUtc()), m_isSwitchedOff(false), m_openArticlesDirectly(false),
m_messageFilters(QList<QPointer<MessageFilter>>()) {
setKind(RootItem::Kind::Feed);
}
@ -41,8 +41,8 @@ Feed::Feed(const Feed& other) : RootItem(other) {
setSource(other.source());
setStatus(other.status(), other.statusString());
setAutoUpdateType(other.autoUpdateType());
setAutoUpdateInitialInterval(other.autoUpdateInitialInterval());
setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval());
setAutoUpdateInterval(other.autoUpdateInterval());
setLastUpdated(other.lastUpdated());
setMessageFilters(other.messageFilters());
setOpenArticlesDirectly(other.openArticlesDirectly());
setIsSwitchedOff(other.isSwitchedOff());
@ -91,8 +91,8 @@ QVariant Feed::data(int column, int role) const {
}
}
int Feed::autoUpdateInitialInterval() const {
return m_autoUpdateInitialInterval;
int Feed::autoUpdateInterval() const {
return m_autoUpdateInterval;
}
int Feed::countOfAllMessages() const {
@ -134,11 +134,11 @@ bool Feed::editViaGui() {
return false;
}
void Feed::setAutoUpdateInitialInterval(int auto_update_interval) {
void Feed::setAutoUpdateInterval(int auto_update_interval) {
// If new initial auto-update interval is set, then
// we should reset time that remains to the next auto-update.
m_autoUpdateInitialInterval = auto_update_interval;
m_autoUpdateRemainingInterval = auto_update_interval;
m_autoUpdateInterval = auto_update_interval;
m_lastUpdated = QDateTime::currentDateTimeUtc();
}
Feed::AutoUpdateType Feed::autoUpdateType() const {
@ -149,14 +149,6 @@ void Feed::setAutoUpdateType(Feed::AutoUpdateType auto_update_type) {
m_autoUpdateType = auto_update_type;
}
int Feed::autoUpdateRemainingInterval() const {
return m_autoUpdateRemainingInterval;
}
void Feed::setAutoUpdateRemainingInterval(int auto_update_remaining_interval) {
m_autoUpdateRemainingInterval = auto_update_remaining_interval;
}
Feed::Status Feed::status() const {
return m_status;
}
@ -219,28 +211,34 @@ QString Feed::getAutoUpdateStatusDescription() const {
switch (autoUpdateType()) {
case AutoUpdateType::DontAutoUpdate:
//: Describes feed auto-update status.
auto_update_string = tr("does not use auto-fetching of articles");
break;
case AutoUpdateType::DefaultAutoUpdate:
//: Describes feed auto-update status.
auto_update_string = qApp->feedReader()->autoUpdateEnabled()
? tr("uses global settings (%n minute(s) to next auto-fetch of articles)",
nullptr,
qApp->feedReader()->autoUpdateRemainingInterval())
: tr("uses global settings (global auto-fetching of articles is disabled)");
if (qApp->feedReader()->autoUpdateEnabled()) {
int secs_to_next =
QDateTime::currentDateTimeUtc()
.secsTo(qApp->feedReader()->lastAutoUpdate().addSecs(qApp->feedReader()->autoUpdateInterval()));
auto_update_string =
tr("uses global settings (%n minute(s) to next auto-fetch of articles)", nullptr, int(secs_to_next / 60.0));
}
else {
auto_update_string = tr("uses global settings, but global auto-fetching of articles is disabled");
}
break;
case AutoUpdateType::SpecificAutoUpdate:
default:
int secs_to_next = QDateTime::currentDateTimeUtc().secsTo(lastUpdated().addSecs(autoUpdateInterval()));
//: Describes feed auto-update status.
auto_update_string = tr("uses specific settings (%n minute(s) to next auto-fetching of new articles)",
nullptr,
autoUpdateRemainingInterval());
int(secs_to_next / 60.0));
break;
}
@ -269,6 +267,14 @@ QString Feed::getStatusDescription() const {
}
}
QDateTime Feed::lastUpdated() const {
return m_lastUpdated;
}
void Feed::setLastUpdated(const QDateTime& last_updated) {
m_lastUpdated = last_updated;
}
bool Feed::isSwitchedOff() const {
return m_isSwitchedOff;
}

View File

@ -53,15 +53,12 @@ class Feed : public RootItem {
void setCountOfAllMessages(int count_all_messages);
void setCountOfUnreadMessages(int count_unread_messages);
int autoUpdateInitialInterval() const;
void setAutoUpdateInitialInterval(int auto_update_interval);
int autoUpdateInterval() const;
void setAutoUpdateInterval(int auto_update_interval);
AutoUpdateType autoUpdateType() const;
void setAutoUpdateType(AutoUpdateType auto_update_type);
int autoUpdateRemainingInterval() const;
void setAutoUpdateRemainingInterval(int auto_update_remaining_interval);
Status status() const;
QString statusString() const;
void setStatus(Feed::Status status, const QString& status_text = {});
@ -80,6 +77,9 @@ class Feed : public RootItem {
void setMessageFilters(const QList<QPointer<MessageFilter>>& messageFilters);
void removeMessageFilter(MessageFilter* filter);
QDateTime lastUpdated() const;
void setLastUpdated(const QDateTime& last_updated);
public slots:
virtual void updateCounts(bool including_total_count);
@ -92,8 +92,8 @@ class Feed : public RootItem {
Status m_status;
QString m_statusString;
AutoUpdateType m_autoUpdateType;
int m_autoUpdateInitialInterval{};
int m_autoUpdateRemainingInterval{};
int m_autoUpdateInterval{}; // In seconds.
QDateTime m_lastUpdated;
bool m_isSwitchedOff;
bool m_openArticlesDirectly;
int m_totalCount{};

View File

@ -44,9 +44,10 @@ void FormFeedDetails::insertCustomTab(QWidget* custom_tab, const QString& title,
void FormFeedDetails::apply() {
// Setup common data for the feed.
m_feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(
m_ui->m_cmbAutoUpdateType->currentIndex()).toInt()));
m_feed->setAutoUpdateInitialInterval(int(m_ui->m_spinAutoUpdateInterval->value()));
m_feed->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType
->itemData(m_ui->m_cmbAutoUpdateType->currentIndex())
.toInt()));
m_feed->setAutoUpdateInterval(int(m_ui->m_spinAutoUpdateInterval->value()));
m_feed->setOpenArticlesDirectly(m_ui->m_cbOpenArticlesAutomatically->isChecked());
m_feed->setIsSwitchedOff(m_ui->m_cbDisableFeed->isChecked());
@ -59,7 +60,8 @@ void FormFeedDetails::apply() {
}
void FormFeedDetails::onAutoUpdateTypeChanged(int new_index) {
Feed::AutoUpdateType auto_update_type = static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(new_index).toInt());
Feed::AutoUpdateType auto_update_type =
static_cast<Feed::AutoUpdateType>(m_ui->m_cmbAutoUpdateType->itemData(new_index).toInt());
switch (auto_update_type) {
case Feed::AutoUpdateType::DontAutoUpdate:
@ -74,7 +76,9 @@ void FormFeedDetails::onAutoUpdateTypeChanged(int new_index) {
void FormFeedDetails::createConnections() {
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormFeedDetails::acceptIfPossible);
connect(m_ui->m_cmbAutoUpdateType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
connect(m_ui->m_cmbAutoUpdateType,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this,
&FormFeedDetails::onAutoUpdateTypeChanged);
}
@ -85,13 +89,12 @@ void FormFeedDetails::loadFeedData() {
tr("Add new feed"));
}
else {
GuiUtilities::applyDialogProperties(*this,
m_feed->fullIcon(),
tr("Edit \"%1\"").arg(m_feed->title()));
GuiUtilities::applyDialogProperties(*this, m_feed->fullIcon(), tr("Edit \"%1\"").arg(m_feed->title()));
}
m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue(int(m_feed->autoUpdateType()))));
m_ui->m_spinAutoUpdateInterval->setValue(m_feed->autoUpdateInitialInterval());
m_ui->m_cmbAutoUpdateType
->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue(int(m_feed->autoUpdateType()))));
m_ui->m_spinAutoUpdateInterval->setValue(m_feed->autoUpdateInterval());
m_ui->m_cbOpenArticlesAutomatically->setChecked(m_feed->openArticlesDirectly());
m_ui->m_cbDisableFeed->setChecked(m_feed->isSwitchedOff());
}
@ -102,11 +105,12 @@ void FormFeedDetails::acceptIfPossible() {
accept();
}
catch (const ApplicationException& ex) {
qApp->showGuiMessage(Notification::Event::GeneralEvent, {
tr("Cannot save feed properties"),
tr("Cannot save changes: %1").arg(ex.message()),
QSystemTrayIcon::MessageIcon::Critical },
{}, {},
qApp->showGuiMessage(Notification::Event::GeneralEvent,
{tr("Cannot save feed properties"),
tr("Cannot save changes: %1").arg(ex.message()),
QSystemTrayIcon::MessageIcon::Critical},
{},
{},
this);
}
}
@ -116,6 +120,7 @@ void FormFeedDetails::initialize() {
m_ui->setupUi(this);
// Setup auto-update options.
m_ui->m_spinAutoUpdateInterval->setMode(TimeSpinBox::Mode::MinutesSeconds);
m_ui->m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL);
m_ui->m_cmbAutoUpdateType->addItem(tr("Fetch articles using global interval"),
QVariant::fromValue(int(Feed::AutoUpdateType::DefaultAutoUpdate)));

View File

@ -380,7 +380,7 @@ QMap<QString, QVariantMap> ServiceRoot::storeCustomFeedsData() {
// TODO: This could potentially call Feed::customDatabaseData() and append it
// to this map and also subsequently restore.
feed_custom_data.insert(QSL("auto_update_interval"), feed->autoUpdateInitialInterval());
feed_custom_data.insert(QSL("auto_update_interval"), feed->autoUpdateInterval());
feed_custom_data.insert(QSL("auto_update_type"), int(feed->autoUpdateType()));
feed_custom_data.insert(QSL("msg_filters"), QVariant::fromValue(feed->messageFilters()));
feed_custom_data.insert(QSL("is_off"), feed->isSwitchedOff());
@ -403,7 +403,7 @@ void ServiceRoot::restoreCustomFeedsData(const QMap<QString, QVariantMap>& data,
Feed* feed = feeds.value(custom_id);
QVariantMap feed_custom_data = i.value();
feed->setAutoUpdateInitialInterval(feed_custom_data.value(QSL("auto_update_interval")).toInt());
feed->setAutoUpdateInterval(feed_custom_data.value(QSL("auto_update_interval")).toInt());
feed
->setAutoUpdateType(static_cast<Feed::AutoUpdateType>(feed_custom_data.value(QSL("auto_update_type")).toInt()));
feed->setMessageFilters(feed_custom_data.value(QSL("msg_filters")).value<QList<QPointer<MessageFilter>>>());