diff --git a/pri/vars.pri b/pri/vars.pri index b721d7297..662116e5b 100644 --- a/pri/vars.pri +++ b/pri/vars.pri @@ -4,7 +4,7 @@ APP_REVERSE_NAME = "com.github.rssguard" APP_LOW_H_NAME = ".rssguard" APP_AUTHOR = "Martin Rotter" APP_COPYRIGHT = "(C) 2011-2020 $$APP_AUTHOR" -APP_VERSION = "3.6.3" +APP_VERSION = "3.7.0" APP_LONG_NAME = "$$APP_NAME $$APP_VERSION" APP_EMAIL = "rotter.martinos@gmail.com" APP_URL = "https://github.com/martinrotter/rssguard" diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index 01b52f763..a16dca377 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -31,7 +31,7 @@ bool FeedDownloader::isUpdateRunning() const { return !m_feeds.isEmpty(); } -void FeedDownloader::updateAvailableFeeds(const QList& msg_filters) { +void FeedDownloader::updateAvailableFeeds() { for (const Feed* feed : m_feeds) { auto* cache = dynamic_cast(feed->getParentServiceRoot()); @@ -42,11 +42,11 @@ void FeedDownloader::updateAvailableFeeds(const QList& msg_filte } while (!m_feeds.isEmpty()) { - updateOneFeed(m_feeds.takeFirst(), msg_filters); + updateOneFeed(m_feeds.takeFirst()); } } -void FeedDownloader::updateFeeds(const QList& feeds, const QList& msg_filters) { +void FeedDownloader::updateFeeds(const QList& feeds) { QMutexLocker locker(m_mutex); if (feeds.isEmpty()) { @@ -62,7 +62,7 @@ void FeedDownloader::updateFeeds(const QList& feeds, const QList& msg_filters) { +void FeedDownloader::updateOneFeed(Feed* feed) { qDebug().nospace() << "Downloading new messages for feed ID " << feed->customId() << " URL: " << feed->url() << " title: " << feed->title() << " in thread: \'" << QThread::currentThreadId() << "\'."; @@ -101,7 +101,7 @@ void FeedDownloader::updateOneFeed(Feed* feed, const QList& msg_ .remove(QRegularExpression(QSL("([\\n\\r])|(^\\s)"))); } - if (!msg_filters.isEmpty()) { + if (!feed->filters().isEmpty()) { // Perform per-message filtering. QJSEngine filter_engine; @@ -117,7 +117,19 @@ void FeedDownloader::updateOneFeed(Feed* feed, const QList& msg_ // Attach live message object to wrapper. msg_obj.setMessage(&msgs[i]); - for (MessageFilter* msg_filter : msg_filters) { + auto feed_filters = feed->filters(); + + for (int i = 0; i < feed_filters.size(); i++) { + QPointer filter = feed_filters.at(i); + + if (filter.isNull()) { + qWarning("Message filter was probably deleted, removing its pointer from list of filters."); + feed_filters.removeAt(i--); + continue; + } + + MessageFilter* msg_filter = filter.data(); + // Call the filtering logic, given function must return integer value from // FilteringAction enumeration. // @@ -129,10 +141,12 @@ void FeedDownloader::updateOneFeed(Feed* feed, const QList& msg_ switch (decision) { case FilteringAction::Accept: + // Message is normally accepted, it could be tweaked by the filter. continue; case FilteringAction::Ignore: + // Remove the message, we do not want it. msgs.removeAt(i--); break; diff --git a/src/librssguard/core/feeddownloader.h b/src/librssguard/core/feeddownloader.h index d23e15d76..3cbb8f31e 100644 --- a/src/librssguard/core/feeddownloader.h +++ b/src/librssguard/core/feeddownloader.h @@ -41,7 +41,7 @@ class FeedDownloader : public QObject { bool isUpdateRunning() const; public slots: - void updateFeeds(const QList& feeds, const QList& msg_filters); + void updateFeeds(const QList& feeds); void stopRunningUpdate(); signals: @@ -50,8 +50,8 @@ class FeedDownloader : public QObject { void updateProgress(const Feed* feed, int current, int total); private: - void updateOneFeed(Feed* feed, const QList& msg_filters); - void updateAvailableFeeds(const QList& msg_filters); + void updateOneFeed(Feed* feed); + void updateAvailableFeeds(); void finalizeUpdate(); QList m_feeds; diff --git a/src/librssguard/core/messagesmodel.cpp b/src/librssguard/core/messagesmodel.cpp index 555ecfeae..e29e94c0a 100644 --- a/src/librssguard/core/messagesmodel.cpp +++ b/src/librssguard/core/messagesmodel.cpp @@ -229,7 +229,7 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { QDateTime dt = TextFactory::parseDateTime(QSqlQueryModel::data(idx, role).value()).toLocalTime(); if (m_customDateFormat.isEmpty()) { - return dt.toString(Qt::DefaultLocaleShortDate); + return QLocale().toString(dt, QLocale::FormatType::ShortFormat); } else { return dt.toString(m_customDateFormat); diff --git a/src/librssguard/gui/dialogs/formabout.cpp b/src/librssguard/gui/dialogs/formabout.cpp index dd1b0192b..cb7fb9695 100644 --- a/src/librssguard/gui/dialogs/formabout.cpp +++ b/src/librssguard/gui/dialogs/formabout.cpp @@ -72,8 +72,8 @@ void FormAbout::loadLicenseAndInformation() { m_ui.m_lblDesc->setText(tr("%8
" "Version: %1 (built on %2/%3)
" "Revision: %4
" "Build date: %5
" "Qt: %6 (compiled against %7)
").arg( qApp->applicationVersion(), APP_SYSTEM_NAME, APP_SYSTEM_VERSION, APP_REVISION, - TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__, - __TIME__)).toString(Qt::DefaultLocaleShortDate), + QLocale().toString(TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__, __TIME__)), + QLocale::FormatType::ShortFormat), qVersion(), QT_VERSION_STR, APP_NAME)); m_ui.m_txtInfo->setText(tr("%5 is a (very) tiny feed reader." diff --git a/src/librssguard/gui/webviewer.cpp b/src/librssguard/gui/webviewer.cpp index 4cbddaf04..695fd4bf5 100644 --- a/src/librssguard/gui/webviewer.cpp +++ b/src/librssguard/gui/webviewer.cpp @@ -127,7 +127,7 @@ void WebViewer::loadMessages(const QList& messages, RootItem* root) { message.m_author), message.m_url, message.m_contents, - message.m_created.toString(Qt::DefaultLocaleShortDate), + QLocale().toString(message.m_created, QLocale::FormatType::ShortFormat), enclosures, message.m_isRead ? "mark-unread" : "mark-read", message.m_isImportant ? "mark-unstarred" : "mark-starred", @@ -201,11 +201,11 @@ bool WebViewer::eventFilter(QObject* object, QEvent* event) { QWheelEvent* wh_event = static_cast(event); if ((wh_event->modifiers() & Qt::KeyboardModifier::ControlModifier) > 0) { - if (wh_event->delta() > 0) { + if (wh_event->angleDelta().y() > 0) { increaseWebPageZoom(); return true; } - else if (wh_event->delta() < 0) { + else if (wh_event->angleDelta().y() < 0) { decreaseWebPageZoom(); return true; } diff --git a/src/librssguard/miscellaneous/externaltool.h b/src/librssguard/miscellaneous/externaltool.h index e9bd5c737..2722069a0 100644 --- a/src/librssguard/miscellaneous/externaltool.h +++ b/src/librssguard/miscellaneous/externaltool.h @@ -10,7 +10,7 @@ class ExternalTool { public: explicit ExternalTool(); ExternalTool(const ExternalTool& other); - explicit ExternalTool(QString executable, QStringList parameters); + explicit ExternalTool(QString executable, QStringList parameters); QString toString(); QString executable() const; diff --git a/src/librssguard/miscellaneous/feedreader.cpp b/src/librssguard/miscellaneous/feedreader.cpp index 9c99f6575..dc56ae1e2 100644 --- a/src/librssguard/miscellaneous/feedreader.cpp +++ b/src/librssguard/miscellaneous/feedreader.cpp @@ -75,7 +75,6 @@ void FeedReader::updateFeeds(const QList& feeds) { m_feedDownloader = new FeedDownloader(); // Downloader setup. - qRegisterMetaType>("QList"); qRegisterMetaType>("QList"); m_feedDownloader->moveToThread(m_feedDownloaderThread); @@ -92,8 +91,7 @@ void FeedReader::updateFeeds(const QList& feeds) { QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", Qt::ConnectionType::QueuedConnection, - Q_ARG(QList, feeds), - Q_ARG(QList, m_messageFilters)); + Q_ARG(QList, feeds)); } void FeedReader::updateAutoUpdateStatus() { @@ -130,6 +128,12 @@ int FeedReader::autoUpdateInitialInterval() const { return m_globalAutoUpdateInitialInterval; } +void FeedReader::loadSaveMessageFilters() { + // TODO: Load all message filters from database. + // All plugin services will hook active filters to + // all feeds. +} + void FeedReader::updateAllFeeds() { updateFeeds(m_feedsModel->rootItem()->getSubTreeFeeds()); } diff --git a/src/librssguard/miscellaneous/feedreader.h b/src/librssguard/miscellaneous/feedreader.h index 82459faf7..182fc37fd 100644 --- a/src/librssguard/miscellaneous/feedreader.h +++ b/src/librssguard/miscellaneous/feedreader.h @@ -26,8 +26,7 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject { explicit FeedReader(QObject* parent = nullptr); virtual ~FeedReader(); - // List of all installed "feed service plugins", including obligatory - // "standard" service entry point. + // List of all installed "feed service plugins". QList feedServices(); // Access to DB cleaner. @@ -51,6 +50,8 @@ class RSSGUARD_DLLSPEC FeedReader : public QObject { int autoUpdateRemainingInterval() const; int autoUpdateInitialInterval() const; + void loadSaveMessageFilters(); + public slots: void updateAllFeeds(); void stopRunningFeedUpdate(); diff --git a/src/librssguard/network-web/adblock/adblockrule.cpp b/src/librssguard/network-web/adblock/adblockrule.cpp index 8e8ac3d06..5e9e199e5 100644 --- a/src/librssguard/network-web/adblock/adblockrule.cpp +++ b/src/librssguard/network-web/adblock/adblockrule.cpp @@ -499,7 +499,7 @@ void AdBlockRule::parseFilter() { void AdBlockRule::parseDomains(const QString& domains, const QChar& separator) { QStringList domainsList = domains.split(separator, QString::SkipEmptyParts); - for (const QString domain : domainsList) { + for (const QString& domain : domainsList) { if (domain.isEmpty()) { continue; } @@ -619,6 +619,7 @@ QString AdBlockRule::createRegExpFromFilter(const QString& filter) const { QList AdBlockRule::createStringMatchers(const QStringList& filters) const { QList matchers; + matchers.reserve(filters.size()); for (const QString& filter : filters) { diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 2fef84e83..7bfc7d5aa 100755 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -18,7 +18,8 @@ Feed::Feed(RootItem* parent) : RootItem(parent), m_url(QString()), m_status(Normal), m_autoUpdateType(DefaultAutoUpdate), - m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL) { + m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL), + m_filters(QList>()) { setKind(RootItemKind::Feed); } @@ -51,6 +52,7 @@ Feed::Feed(const Feed& other) : RootItem(other) { setAutoUpdateType(other.autoUpdateType()); setAutoUpdateInitialInterval(other.autoUpdateInitialInterval()); setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval()); + setFilters(other.filters()); } Feed::~Feed() = default; @@ -241,9 +243,11 @@ QString Feed::getAutoUpdateStatusDescription() const { case DefaultAutoUpdate: //: Describes feed auto-update status. - auto_update_string = tr("uses global settings (%n minute(s) to next auto-update)", - nullptr, - qApp->feedReader()->autoUpdateRemainingInterval()); + auto_update_string = qApp->feedReader()->autoUpdateEnabled() + ? tr("uses global settings (%n minute(s) to next auto-update)", + nullptr, + qApp->feedReader()->autoUpdateRemainingInterval()) + : tr("uses global settings (global feed auto-updating is disabled)"); break; case SpecificAutoUpdate: @@ -276,7 +280,18 @@ QString Feed::getStatusDescription() const { } } +QList> Feed::filters() const { + return m_filters; +} + +void Feed::setFilters(const QList>& filters) { + m_filters = filters; +} + QString Feed::additionalTooltip() const { return tr("Auto-update status: %1\n" - "Status: %2").arg(getAutoUpdateStatusDescription(), getStatusDescription()); + "Active message filters: %2\n" + "Status: %3").arg(getAutoUpdateStatusDescription(), + QString::number(m_filters.size()), + getStatusDescription()); } diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index b6992dbf3..8bb93ff05 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -6,7 +6,9 @@ #include "services/abstract/rootitem.h" #include "core/message.h" +#include "core/messagefilter.h" +#include #include // Base class for "feed" nodes. @@ -67,6 +69,9 @@ class Feed : public RootItem { QString url() const; void setUrl(const QString& url); + QList> filters() const; + void setFilters(const QList>& filters); + bool markAsReadUnread(ReadStatus status); bool cleanMessages(bool clean_read_only); @@ -88,6 +93,7 @@ class Feed : public RootItem { int m_autoUpdateRemainingInterval{}; int m_totalCount{}; int m_unreadCount{}; + QList> m_filters; }; Q_DECLARE_METATYPE(Feed::AutoUpdateType) diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index 2c5c47d36..addb318fd 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -163,9 +163,9 @@ QString TtRssServiceRoot::additionalTooltip() const { "Last error: %3\nLast login on: %4").arg(m_network->username(), m_network->url(), NetworkFactory::networkErrorText(m_network->lastError()), - m_network->lastLoginTime().isValid() ? - m_network->lastLoginTime().toString(Qt::DefaultLocaleShortDate) : - QSL("-")); + m_network->lastLoginTime().isValid() + ? QLocale().toString(m_network->lastLoginTime(), QLocale::FormatType::ShortFormat) + : QSL("-")); } TtRssNetworkFactory* TtRssServiceRoot::network() const { diff --git a/src/rssguard/main.cpp b/src/rssguard/main.cpp index f0c2e29b2..db85bcb90 100755 --- a/src/rssguard/main.cpp +++ b/src/rssguard/main.cpp @@ -77,6 +77,7 @@ int main(int argc, char* argv[]) { qApp->loadDynamicShortcuts(); qApp->hideOrShowMainForm(); + qApp->feedReader()->loadSaveMessageFilters(); qApp->feedReader()->feedsModel()->loadActivatedServiceAccounts(); qApp->showTrayIcon(); qApp->offerChanges();