work on toasts, unify article sanitization
This commit is contained in:
parent
69dc7e0a32
commit
46fe50df91
@ -8,6 +8,8 @@
|
||||
<file>./graphics/Breeze/categories/32/applications-system.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/arrow-down.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/arrow-down-double.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/arrow-left.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/arrow-right.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/arrow-up.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/arrow-up-double.svg</file>
|
||||
<file>./graphics/Breeze/actions/32/call-start.svg</file>
|
||||
@ -99,6 +101,8 @@
|
||||
<file>./graphics/Breeze Dark/categories/32/applications-system.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/arrow-down.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/arrow-down-double.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/arrow-left.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/arrow-right.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/arrow-up.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/arrow-up-double.svg</file>
|
||||
<file>./graphics/Breeze Dark/actions/32/call-start.svg</file>
|
||||
@ -274,6 +278,8 @@
|
||||
<file>./graphics/Numix/22/categories/applications-system.svg</file>
|
||||
<file>./graphics/Numix/22/actions/arrow-down.svg</file>
|
||||
<file>./graphics/Numix/22/actions/arrow-down-double.svg</file>
|
||||
<file>./graphics/Numix/22/actions/arrow-left.svg</file>
|
||||
<file>./graphics/Numix/22/actions/arrow-right.svg</file>
|
||||
<file>./graphics/Numix/22/actions/arrow-up.svg</file>
|
||||
<file>./graphics/Numix/22/actions/arrow-up-double.svg</file>
|
||||
<file>./graphics/Numix/22/actions/browser-download.svg</file>
|
||||
|
@ -1,4 +1,6 @@
|
||||
set(SOURCES
|
||||
core/articlelistnotificationmodel.cpp
|
||||
core/articlelistnotificationmodel.h
|
||||
core/feeddownloader.cpp
|
||||
core/feeddownloader.h
|
||||
core/feedsmodel.cpp
|
||||
|
23
src/librssguard/core/articlelistnotificationmodel.cpp
Normal file
23
src/librssguard/core/articlelistnotificationmodel.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#include "core/articlelistnotificationmodel.h"
|
||||
|
||||
ArticleListNotificationModel::ArticleListNotificationModel(QObject* parent)
|
||||
: QAbstractListModel(parent), m_currentPage(-1) {}
|
||||
|
||||
ArticleListNotificationModel::~ArticleListNotificationModel() {}
|
||||
|
||||
void ArticleListNotificationModel::setArticles(const QList<Message>& msgs) {
|
||||
m_articles = msgs;
|
||||
m_currentPage = 0;
|
||||
}
|
||||
|
||||
void ArticleListNotificationModel::nextPage() {}
|
||||
|
||||
void ArticleListNotificationModel::previousPage() {}
|
||||
|
||||
int ArticleListNotificationModel::rowCount(const QModelIndex& parent) const {}
|
||||
|
||||
int ArticleListNotificationModel::columnCount(const QModelIndex& parent) const {}
|
||||
|
||||
QVariant ArticleListNotificationModel::data(const QModelIndex& index, int role) const {}
|
33
src/librssguard/core/articlelistnotificationmodel.h
Normal file
33
src/librssguard/core/articlelistnotificationmodel.h
Normal file
@ -0,0 +1,33 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef ARTICLELISTNOTIFICATIONMODEL_H
|
||||
#define ARTICLELISTNOTIFICATIONMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "core/message.h"
|
||||
|
||||
class ArticleListNotificationModel : public QAbstractListModel {
|
||||
public:
|
||||
explicit ArticleListNotificationModel(QObject* parent = nullptr);
|
||||
virtual ~ArticleListNotificationModel();
|
||||
|
||||
void setArticles(const QList<Message>& msgs);
|
||||
|
||||
void nextPage();
|
||||
void previousPage();
|
||||
|
||||
virtual int rowCount(const QModelIndex& parent) const;
|
||||
virtual int columnCount(const QModelIndex& parent) const;
|
||||
virtual QVariant data(const QModelIndex& index, int role) const;
|
||||
|
||||
signals:
|
||||
void nextPagePossibleChanged(bool possible);
|
||||
void previousPagePossibleChanged(bool possible);
|
||||
|
||||
private:
|
||||
QList<Message> m_articles;
|
||||
int m_currentPage;
|
||||
};
|
||||
|
||||
#endif // ARTICLELISTNOTIFICATIONMODEL_H
|
@ -413,15 +413,17 @@ void FeedDownloader::updateOneFeed(ServiceRoot* acc,
|
||||
<< "microseconds.";
|
||||
|
||||
if (feed->status() != Feed::Status::NewMessages) {
|
||||
feed->setStatus(updated_messages.first > 0 || updated_messages.second > 0 ? Feed::Status::NewMessages
|
||||
: Feed::Status::Normal);
|
||||
feed->setStatus((!updated_messages.m_all.isEmpty() || !updated_messages.m_unread.isEmpty())
|
||||
? Feed::Status::NewMessages
|
||||
: Feed::Status::Normal);
|
||||
}
|
||||
|
||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << updated_messages << " messages for feed " << feed->customId()
|
||||
<< " stored in DB.";
|
||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << updated_messages.m_unread.size() << " unread messages and"
|
||||
<< NONQUOTE_W_SPACE(updated_messages.m_all.size()) "total messages for feed"
|
||||
<< QUOTE_W_SPACE(feed->customId()) << "stored in DB.";
|
||||
|
||||
if (updated_messages.first > 0) {
|
||||
m_results.appendUpdatedFeed({feed, updated_messages.first});
|
||||
if (!updated_messages.m_unread.isEmpty()) {
|
||||
m_results.appendUpdatedFeed(feed, updated_messages.m_unread);
|
||||
}
|
||||
}
|
||||
catch (const FeedFetchException& feed_ex) {
|
||||
@ -445,7 +447,6 @@ void FeedDownloader::finalizeUpdate() {
|
||||
qDebugNN << LOGSEC_FEEDDOWNLOADER << "Finished feed updates in thread"
|
||||
<< QUOTE_W_SPACE_DOT(QThread::currentThreadId());
|
||||
|
||||
m_results.sort();
|
||||
m_feeds.clear();
|
||||
|
||||
// Update of feeds has finished.
|
||||
@ -528,7 +529,8 @@ QString FeedDownloadResults::overview(int how_many_feeds) const {
|
||||
QStringList result;
|
||||
|
||||
for (int i = 0, number_items_output = qMin(how_many_feeds, m_updatedFeeds.size()); i < number_items_output; i++) {
|
||||
result.append(m_updatedFeeds.at(i).first->title() + QSL(": ") + QString::number(m_updatedFeeds.at(i).second));
|
||||
result.append(m_updatedFeeds.keys().at(i)->title() + QSL(": ") +
|
||||
QString::number(m_updatedFeeds.value(m_updatedFeeds.keys().at(i)).size()));
|
||||
}
|
||||
|
||||
QString res_str = result.join(QSL("\n"));
|
||||
@ -540,22 +542,14 @@ QString FeedDownloadResults::overview(int how_many_feeds) const {
|
||||
return res_str;
|
||||
}
|
||||
|
||||
void FeedDownloadResults::appendUpdatedFeed(const QPair<Feed*, int>& feed) {
|
||||
m_updatedFeeds.append(feed);
|
||||
}
|
||||
|
||||
void FeedDownloadResults::sort() {
|
||||
std::sort(m_updatedFeeds.begin(),
|
||||
m_updatedFeeds.end(),
|
||||
[](const QPair<Feed*, int>& lhs, const QPair<Feed*, int>& rhs) {
|
||||
return lhs.second > rhs.second;
|
||||
});
|
||||
void FeedDownloadResults::appendUpdatedFeed(Feed* feed, const QList<Message>& updated_unread_msgs) {
|
||||
m_updatedFeeds.insert(feed, updated_unread_msgs);
|
||||
}
|
||||
|
||||
void FeedDownloadResults::clear() {
|
||||
m_updatedFeeds.clear();
|
||||
}
|
||||
|
||||
QList<QPair<Feed*, int>> FeedDownloadResults::updatedFeeds() const {
|
||||
QHash<Feed*, QList<Message>> FeedDownloadResults::updatedFeeds() const {
|
||||
return m_updatedFeeds;
|
||||
}
|
||||
|
@ -5,29 +5,28 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QPair>
|
||||
|
||||
#include "core/message.h"
|
||||
#include "exceptions/applicationexception.h"
|
||||
#include "services/abstract/cacheforserviceroot.h"
|
||||
#include "services/abstract/feed.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QHash>
|
||||
#include <QPair>
|
||||
|
||||
class MessageFilter;
|
||||
|
||||
// Represents results of batch feed updates.
|
||||
class FeedDownloadResults {
|
||||
public:
|
||||
QList<QPair<Feed*, int>> updatedFeeds() const;
|
||||
QHash<Feed*, QList<Message>> updatedFeeds() const;
|
||||
QString overview(int how_many_feeds) const;
|
||||
|
||||
void appendUpdatedFeed(const QPair<Feed*, int>& feed);
|
||||
void sort();
|
||||
void appendUpdatedFeed(Feed* feed, const QList<Message>& updated_unread_msgs);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
// QString represents title if the feed, int represents count of newly downloaded messages.
|
||||
QList<QPair<Feed*, int>> m_updatedFeeds;
|
||||
QHash<Feed*, QList<Message>> m_updatedFeeds;
|
||||
};
|
||||
|
||||
struct FeedUpdateRequest {
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
#include "core/message.h"
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "network-web/webfactory.h"
|
||||
#include "services/abstract/feed.h"
|
||||
#include "services/abstract/label.h"
|
||||
|
||||
@ -75,6 +77,8 @@ Message::Message() {
|
||||
|
||||
void Message::sanitize(const Feed* feed, bool fix_future_datetimes) {
|
||||
// Sanitize title.
|
||||
m_title = qApp->web()->stripTags(qApp->web()->unescapeHtml(m_title));
|
||||
|
||||
m_title = m_title
|
||||
|
||||
// Remove non-breaking spaces.
|
||||
@ -89,6 +93,9 @@ void Message::sanitize(const Feed* feed, bool fix_future_datetimes) {
|
||||
// Remove non-breaking zero-width spaces.
|
||||
.remove(QChar(65279));
|
||||
|
||||
// Sanitize author.
|
||||
m_author = qApp->web()->stripTags(qApp->web()->unescapeHtml(m_author));
|
||||
|
||||
// Sanitize URL.
|
||||
m_url = m_url.trimmed();
|
||||
|
||||
|
@ -1354,7 +1354,7 @@ QHash<QString, QStringList> DatabaseQueries::bagsOfMessages(const QSqlDatabase&
|
||||
return ids;
|
||||
}
|
||||
|
||||
QPair<int, int> DatabaseQueries::updateMessages(const QSqlDatabase& db,
|
||||
UpdatedArticles DatabaseQueries::updateMessages(const QSqlDatabase& db,
|
||||
QList<Message>& messages,
|
||||
Feed* feed,
|
||||
bool force_update,
|
||||
@ -1362,10 +1362,10 @@ QPair<int, int> DatabaseQueries::updateMessages(const QSqlDatabase& db,
|
||||
bool* ok) {
|
||||
if (messages.isEmpty()) {
|
||||
*ok = true;
|
||||
return {0, 0};
|
||||
return {};
|
||||
}
|
||||
|
||||
QPair<int, int> updated_messages = {0, 0};
|
||||
UpdatedArticles updated_messages;
|
||||
int account_id = feed->getParentServiceRoot()->accountId();
|
||||
auto feed_custom_id = feed->customId();
|
||||
|
||||
@ -1615,10 +1615,10 @@ QPair<int, int> DatabaseQueries::updateMessages(const QSqlDatabase& db,
|
||||
<< QUOTE_W_SPACE(message.m_url) << "in DB.";
|
||||
|
||||
if (!message.m_isRead) {
|
||||
updated_messages.first++;
|
||||
updated_messages.m_unread.append(message);
|
||||
}
|
||||
|
||||
updated_messages.second++;
|
||||
updated_messages.m_all.append(message);
|
||||
message.m_insertedUpdated = true;
|
||||
}
|
||||
else if (query_update.lastError().isValid()) {
|
||||
@ -1655,10 +1655,10 @@ QPair<int, int> DatabaseQueries::updateMessages(const QSqlDatabase& db,
|
||||
}
|
||||
|
||||
if (!msg->m_isRead) {
|
||||
updated_messages.first++;
|
||||
updated_messages.m_unread.append(*msg);
|
||||
}
|
||||
|
||||
updated_messages.second++;
|
||||
updated_messages.m_all.append(*msg);
|
||||
msg->m_insertedUpdated = true;
|
||||
|
||||
vals.append(QSL("\n(':feed', ':title', :is_read, :is_important, :is_deleted, "
|
||||
@ -1742,10 +1742,10 @@ QPair<int, int> DatabaseQueries::updateMessages(const QSqlDatabase& db,
|
||||
// but its assigned labels were changed. Therefore we must count article
|
||||
// as updated.
|
||||
if (!message.m_isRead) {
|
||||
updated_messages.first++;
|
||||
updated_messages.m_unread.append(message);
|
||||
}
|
||||
|
||||
updated_messages.second++;
|
||||
updated_messages.m_all.append(message);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -21,11 +21,6 @@
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
struct ArticleCounts {
|
||||
int m_total = -1;
|
||||
int m_unread = -1;
|
||||
};
|
||||
|
||||
class DatabaseQueries {
|
||||
public:
|
||||
static QMap<int, QString> messageTableAttributes(bool only_msg_table, bool is_sqlite);
|
||||
@ -162,7 +157,7 @@ class DatabaseQueries {
|
||||
static void createOverwriteAccount(const QSqlDatabase& db, ServiceRoot* account);
|
||||
|
||||
// Returns counts of updated messages <unread, all>.
|
||||
static QPair<int, int> updateMessages(const QSqlDatabase& db,
|
||||
static UpdatedArticles updateMessages(const QSqlDatabase& db,
|
||||
QList<Message>& messages,
|
||||
Feed* feed,
|
||||
bool force_update,
|
||||
|
@ -100,9 +100,10 @@
|
||||
#define MAX_THREADPOOL_THREADS 32
|
||||
#define WEB_BROWSER_SCROLL_STEP 50.0
|
||||
|
||||
#define NOTIFICATIONS_MARGIN 16
|
||||
#define NOTIFICATIONS_WIDTH 256
|
||||
#define NOTIFICATIONS_TIMEOUT 15s
|
||||
#define NOTIFICATIONS_MARGIN 16
|
||||
#define NOTIFICATIONS_WIDTH 256
|
||||
#define NOTIFICATIONS_TIMEOUT 15s
|
||||
#define NOTIFICATIONS_PAGE_SIZE 10
|
||||
|
||||
#define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8"
|
||||
#define GOOGLE_SUGGEST_URL "http://suggestqueries.google.com/complete/search?output=toolbar&hl=en&q=%1"
|
||||
|
@ -14,4 +14,14 @@ typedef QList<QPair<int, RootItem*>> Assignment;
|
||||
typedef QPair<int, RootItem*> AssignmentItem;
|
||||
typedef QPair<Message, RootItem::Importance> ImportanceChange;
|
||||
|
||||
struct ArticleCounts {
|
||||
int m_total = -1;
|
||||
int m_unread = -1;
|
||||
};
|
||||
|
||||
struct UpdatedArticles {
|
||||
QList<Message> m_unread;
|
||||
QList<Message> m_all;
|
||||
};
|
||||
|
||||
#endif // TYPEDEFS_H
|
||||
|
@ -2,9 +2,21 @@
|
||||
|
||||
#include "gui/notifications/articlelistnotification.h"
|
||||
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
|
||||
ArticleListNotification::ArticleListNotification(QWidget* parent) : BaseToastNotification(parent) {
|
||||
m_ui.setupUi(this);
|
||||
|
||||
setupCloseButton(m_ui.m_btnClose);
|
||||
setupTimedClosing();
|
||||
|
||||
m_ui.m_btnNextPage->setIcon(qApp->icons()->fromTheme(QSL("arrow-right"), QSL("stock_right")));
|
||||
m_ui.m_btnPreviousPage->setIcon(qApp->icons()->fromTheme(QSL("arrow-left"), QSL("stock_left")));
|
||||
m_ui.m_btnOpenArticleList->setIcon(qApp->icons()->fromTheme(QSL("view-list-details")));
|
||||
m_ui.m_btnOpenWebBrowser->setIcon(qApp->icons()->fromTheme(QSL("document-open")));
|
||||
}
|
||||
|
||||
void ArticleListNotification::loadResults(const QHash<Feed*, QList<Message>>& new_messages) {
|
||||
setupTimedClosing();
|
||||
|
||||
m_ui.m_treeArticles->setModel()
|
||||
}
|
||||
|
@ -5,14 +5,20 @@
|
||||
|
||||
#include "gui/notifications/basetoastnotification.h"
|
||||
|
||||
#include "core/message.h"
|
||||
|
||||
#include "ui_articlelistnotification.h"
|
||||
|
||||
class Feed;
|
||||
|
||||
class ArticleListNotification : public BaseToastNotification {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ArticleListNotification(QWidget* parent = nullptr);
|
||||
|
||||
void loadResults(const QHash<Feed*, QList<Message>>& new_messages);
|
||||
|
||||
private:
|
||||
Ui::ArticleListNotification m_ui;
|
||||
};
|
||||
|
130
src/librssguard/gui/notifications/articlelistnotification.ui
Normal file
130
src/librssguard/gui/notifications/articlelistnotification.ui
Normal file
@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ArticleListNotification</class>
|
||||
<widget class="QDialog" name="ArticleListNotification">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>338</width>
|
||||
<height>271</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTreeView" name="m_treeArticles">
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="m_titleLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="m_lblTitle">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PlainToolButton" name="m_btnClose">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="PlainToolButton" name="m_btnPreviousPage">
|
||||
<property name="toolTip">
|
||||
<string>Go to previous page</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PlainToolButton" name="m_btnNextPage">
|
||||
<property name="toolTip">
|
||||
<string>Go to next page</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PlainToolButton" name="m_btnOpenArticleList">
|
||||
<property name="toolTip">
|
||||
<string>Open article in article list</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PlainToolButton" name="m_btnOpenWebBrowser">
|
||||
<property name="toolTip">
|
||||
<string>Open article in web browser</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>PlainToolButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>plaintoolbutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>m_btnClose</tabstop>
|
||||
<tabstop>m_treeArticles</tabstop>
|
||||
<tabstop>m_btnPreviousPage</tabstop>
|
||||
<tabstop>m_btnNextPage</tabstop>
|
||||
<tabstop>m_btnOpenArticleList</tabstop>
|
||||
<tabstop>m_btnOpenWebBrowser</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -6,12 +6,13 @@
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QTimer>
|
||||
#include <QTimerEvent>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
BaseToastNotification::BaseToastNotification(QWidget* parent) : QDialog(parent) {
|
||||
BaseToastNotification::BaseToastNotification(QWidget* parent) : QDialog(parent), m_timerId(-1) {
|
||||
setAttribute(Qt::WidgetAttribute::WA_ShowWithoutActivating);
|
||||
setFixedWidth(NOTIFICATIONS_WIDTH);
|
||||
setFocusPolicy(Qt::FocusPolicy::NoFocus);
|
||||
@ -39,8 +40,15 @@ void BaseToastNotification::setupCloseButton(QAbstractButton* btn) {
|
||||
connect(btn, &QAbstractButton::clicked, this, &BaseToastNotification::close);
|
||||
}
|
||||
|
||||
void BaseToastNotification::stopTimedClosing() {
|
||||
killTimer(m_timerId);
|
||||
m_timerId = -1;
|
||||
}
|
||||
|
||||
void BaseToastNotification::setupTimedClosing() {
|
||||
QTimer::singleShot(NOTIFICATIONS_TIMEOUT, this, &BaseToastNotification::close);
|
||||
if (m_timerId < 0) {
|
||||
m_timerId = startTimer(NOTIFICATIONS_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseToastNotification::eventFilter(QObject* watched, QEvent* event) {
|
||||
@ -48,12 +56,28 @@ bool BaseToastNotification::eventFilter(QObject* watched, QEvent* event) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if (event->type() == QEvent::Type::Enter) {
|
||||
stopTimedClosing();
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::Type::Leave) {
|
||||
setupTimedClosing();
|
||||
}
|
||||
|
||||
return QDialog::eventFilter(watched, event);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseToastNotification::closeEvent(QCloseEvent* event) {
|
||||
stopTimedClosing();
|
||||
emit closeRequested(this);
|
||||
}
|
||||
|
||||
void BaseToastNotification::reject() {}
|
||||
|
||||
void BaseToastNotification::timerEvent(QTimerEvent* event) {
|
||||
if (event->timerId() == m_timerId) {
|
||||
stopTimedClosing();
|
||||
emit closeRequested(this);
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,12 @@ class BaseToastNotification : public QDialog {
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||
virtual void timerEvent(QTimerEvent* event);
|
||||
virtual void closeEvent(QCloseEvent* event);
|
||||
|
||||
void setupCloseButton(QAbstractButton* btn);
|
||||
void setupTimedClosing();
|
||||
void setupCloseButton(QAbstractButton* btn);
|
||||
void stopTimedClosing();
|
||||
|
||||
signals:
|
||||
void closeRequested(BaseToastNotification* notif);
|
||||
|
@ -43,7 +43,10 @@ void ToastNotification::loadNotification(Notification::Event event, const GuiMes
|
||||
|
||||
if (action.m_action) {
|
||||
m_ui.m_btnAction->setText(action.m_title.isEmpty() ? tr("Do it!") : action.m_title);
|
||||
connect(m_ui.m_btnAction, &QPushButton::clicked, this, action.m_action);
|
||||
connect(m_ui.m_btnAction, &QPushButton::clicked, this, [this, action]() {
|
||||
action.m_action();
|
||||
emit closeRequested(this);
|
||||
});
|
||||
}
|
||||
else {
|
||||
m_ui.m_mainLayout->removeItem(m_ui.m_actionLayout);
|
||||
|
@ -10,9 +10,6 @@
|
||||
<height>143</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="m_mainLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
|
@ -12,6 +12,23 @@
|
||||
#include <QScreen>
|
||||
#include <QWindow>
|
||||
|
||||
QString ToastNotificationsManager::textForPosition(ToastNotificationsManager::NotificationPosition pos) {
|
||||
switch (pos) {
|
||||
case TopLeft:
|
||||
return QObject::tr("top-left");
|
||||
|
||||
case TopRight:
|
||||
return QObject::tr("top-right");
|
||||
|
||||
case BottomLeft:
|
||||
return QObject::tr("bottom-left");
|
||||
|
||||
case BottomRight:
|
||||
default:
|
||||
return QObject::tr("bottom-right");
|
||||
}
|
||||
}
|
||||
|
||||
ToastNotificationsManager::ToastNotificationsManager(NotificationPosition position, int screen, QObject* parent)
|
||||
: QObject(parent), m_position(position), m_screen(screen), m_articleListNotification(nullptr) {}
|
||||
|
||||
@ -50,9 +67,26 @@ void ToastNotificationsManager::clear() {
|
||||
void ToastNotificationsManager::showNotification(Notification::Event event,
|
||||
const GuiMessage& msg,
|
||||
const GuiAction& action) {
|
||||
ToastNotification* notif = new ToastNotification(event, msg, action, qApp->mainFormWidget());
|
||||
BaseToastNotification* notif;
|
||||
|
||||
hookNotification(notif);
|
||||
if (!msg.m_feedFetchResults.updatedFeeds().isEmpty()) {
|
||||
if (m_articleListNotification == nullptr) {
|
||||
m_articleListNotification = new ArticleListNotification();
|
||||
hookNotification(m_articleListNotification);
|
||||
}
|
||||
else if (m_activeNotifications.contains(m_articleListNotification)) {
|
||||
// Article notification is somewhere in list, clear first to move it to first positon.
|
||||
closeNotification(m_articleListNotification, false);
|
||||
}
|
||||
|
||||
m_articleListNotification->loadResults(msg.m_feedFetchResults.updatedFeeds());
|
||||
|
||||
notif = m_articleListNotification;
|
||||
}
|
||||
else {
|
||||
notif = new ToastNotification(event, msg, action, qApp->mainFormWidget());
|
||||
hookNotification(notif);
|
||||
}
|
||||
|
||||
auto* screen = moveToProperScreen(notif);
|
||||
|
||||
@ -76,39 +110,6 @@ void ToastNotificationsManager::showNotification(Notification::Event event,
|
||||
m_activeNotifications.prepend(notif);
|
||||
}
|
||||
|
||||
void ToastNotificationsManager::showNotification(const QList<Message>& new_messages) {
|
||||
if (m_articleListNotification == nullptr) {
|
||||
m_articleListNotification = new ArticleListNotification();
|
||||
hookNotification(m_articleListNotification);
|
||||
}
|
||||
|
||||
if (!m_activeNotifications.isEmpty() && m_activeNotifications.first() != m_articleListNotification) {
|
||||
// Article notification is somewhere in list, clear first to move it to first positon.
|
||||
closeNotification(m_articleListNotification, false);
|
||||
}
|
||||
|
||||
auto* screen = moveToProperScreen(m_articleListNotification);
|
||||
|
||||
// Insert new notification into free space.
|
||||
m_articleListNotification->show();
|
||||
|
||||
auto notif_new_pos = cornerForNewNotification(screen->availableGeometry());
|
||||
|
||||
// Make sure notification is finally resized.
|
||||
m_articleListNotification->adjustSize();
|
||||
qApp->processEvents();
|
||||
|
||||
// Move notification, at this point we already need to know its precise size.
|
||||
moveNotificationToCorner(m_articleListNotification, notif_new_pos);
|
||||
|
||||
// Remove out-of-bounds old notifications and shift existing
|
||||
// ones to make space for new notifications.
|
||||
removeOutOfBoundsNotifications(m_articleListNotification->height());
|
||||
makeSpaceForNotification(m_articleListNotification->height());
|
||||
|
||||
m_activeNotifications.prepend(m_articleListNotification);
|
||||
}
|
||||
|
||||
void ToastNotificationsManager::closeNotification(BaseToastNotification* notif, bool delete_from_memory) {
|
||||
auto notif_idx = m_activeNotifications.indexOf(notif);
|
||||
|
||||
@ -160,7 +161,7 @@ QPoint ToastNotificationsManager::cornerForNewNotification(QRect screen_rect) {
|
||||
|
||||
void ToastNotificationsManager::hookNotification(BaseToastNotification* notif) {
|
||||
connect(notif, &BaseToastNotification::closeRequested, this, [this](BaseToastNotification* notif) {
|
||||
closeNotification(notif, false);
|
||||
closeNotification(notif, notif != m_articleListNotification);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,10 @@ class ToastNotificationsManager : public QObject {
|
||||
BottomRight = 3
|
||||
};
|
||||
|
||||
Q_ENUM(NotificationPosition)
|
||||
|
||||
static QString textForPosition(ToastNotificationsManager::NotificationPosition pos);
|
||||
|
||||
explicit ToastNotificationsManager(ToastNotificationsManager::NotificationPosition position,
|
||||
int screen,
|
||||
QObject* parent = nullptr);
|
||||
@ -41,7 +45,6 @@ class ToastNotificationsManager : public QObject {
|
||||
public slots:
|
||||
void clear();
|
||||
void showNotification(Notification::Event event, const GuiMessage& msg, const GuiAction& action);
|
||||
void showNotification(const QList<Message>& new_messages);
|
||||
|
||||
private slots:
|
||||
void closeNotification(BaseToastNotification* notif, bool delete_from_memory);
|
||||
|
@ -26,6 +26,7 @@ HelpSpoiler::HelpSpoiler(QWidget* parent)
|
||||
m_btnToggle->setCheckable(true);
|
||||
m_btnToggle->setChecked(false);
|
||||
|
||||
m_content->setStyleSheet(QSL("QScrollArea { border: 1px solid %1; }").arg(palette().windowText().color().name()));
|
||||
m_content->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);
|
||||
m_content->setMaximumHeight(0);
|
||||
m_content->setMinimumHeight(0);
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "miscellaneous/settings.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QMetaEnum>
|
||||
#include <QScreen>
|
||||
|
||||
SettingsNotifications::SettingsNotifications(Settings* settings, QWidget* parent) : SettingsPanel(settings, parent) {
|
||||
m_ui.setupUi(this);
|
||||
@ -25,6 +27,14 @@ SettingsNotifications::SettingsNotifications(Settings* settings, QWidget* parent
|
||||
connect(m_ui.m_rbNativeNotifications, &QRadioButton::toggled, this, &SettingsNotifications::dirtifySettings);
|
||||
connect(m_ui.m_rbNativeNotifications, &QRadioButton::toggled, this, &SettingsNotifications::requireRestart);
|
||||
|
||||
connect(m_ui.m_sbScreen, &QSpinBox::valueChanged, this, &SettingsNotifications::dirtifySettings);
|
||||
connect(m_ui.m_sbScreen, &QSpinBox::valueChanged, this, &SettingsNotifications::requireRestart);
|
||||
|
||||
m_ui.m_sbScreen->setMinimum(-1);
|
||||
m_ui.m_sbScreen->setMaximum(QGuiApplication::screens().size() - 1);
|
||||
|
||||
connect(m_ui.m_sbScreen, &QSpinBox::valueChanged, this, &SettingsNotifications::showScreenInfo);
|
||||
|
||||
connect(m_ui.m_cbCustomNotificationsPosition,
|
||||
&QComboBox::currentIndexChanged,
|
||||
this,
|
||||
@ -33,6 +43,15 @@ SettingsNotifications::SettingsNotifications(Settings* settings, QWidget* parent
|
||||
&QComboBox::currentIndexChanged,
|
||||
this,
|
||||
&SettingsNotifications::requireRestart);
|
||||
|
||||
QMetaEnum enm = QMetaEnum::fromType<ToastNotificationsManager::NotificationPosition>();
|
||||
|
||||
for (int i = 0; i < enm.keyCount(); i++) {
|
||||
m_ui.m_cbCustomNotificationsPosition
|
||||
->addItem(ToastNotificationsManager::
|
||||
textForPosition(ToastNotificationsManager::NotificationPosition(enm.value(i))),
|
||||
enm.value(i));
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsNotifications::loadSettings() {
|
||||
@ -43,6 +62,16 @@ void SettingsNotifications::loadSettings() {
|
||||
->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::EnableNotifications)).toBool());
|
||||
m_ui.m_editor->loadNotifications(qApp->notifications()->allNotifications());
|
||||
|
||||
m_ui.m_rbNativeNotifications
|
||||
->setChecked(!settings()->value(GROUP(GUI), SETTING(GUI::UseToastNotifications)).toBool());
|
||||
m_ui.m_sbScreen->setValue(settings()->value(GROUP(GUI), SETTING(GUI::ToastNotificationsScreen)).toInt());
|
||||
|
||||
m_ui.m_cbCustomNotificationsPosition
|
||||
->setCurrentIndex(m_ui.m_cbCustomNotificationsPosition
|
||||
->findData(settings()
|
||||
->value(GROUP(GUI), SETTING(GUI::ToastNotificationsPosition))
|
||||
.value<ToastNotificationsManager::NotificationPosition>()));
|
||||
|
||||
onEndLoadSettings();
|
||||
}
|
||||
|
||||
@ -53,5 +82,29 @@ void SettingsNotifications::saveSettings() {
|
||||
settings()->setValue(GROUP(GUI), GUI::EnableNotifications, m_ui.m_checkEnableNotifications->isChecked());
|
||||
qApp->notifications()->save(m_ui.m_editor->allNotifications(), settings());
|
||||
|
||||
settings()->setValue(GROUP(GUI), GUI::UseToastNotifications, m_ui.m_rbCustomNotifications->isChecked());
|
||||
settings()->setValue(GROUP(GUI), GUI::ToastNotificationsScreen, m_ui.m_sbScreen->value());
|
||||
|
||||
settings()->setValue(GROUP(GUI),
|
||||
GUI::ToastNotificationsPosition,
|
||||
m_ui.m_cbCustomNotificationsPosition->currentData()
|
||||
.value<ToastNotificationsManager::NotificationPosition>());
|
||||
|
||||
onEndSaveSettings();
|
||||
}
|
||||
|
||||
void SettingsNotifications::showScreenInfo(int index) {
|
||||
QScreen* scr;
|
||||
|
||||
if (index < 0 || index >= QGuiApplication::screens().size()) {
|
||||
scr = QGuiApplication::primaryScreen();
|
||||
}
|
||||
else {
|
||||
scr = QGuiApplication::screens().at(index);
|
||||
}
|
||||
|
||||
m_ui.m_lblScreenInfo->setText(QSL("%1 (%2x%3)")
|
||||
.arg(scr->name(),
|
||||
QString::number(scr->virtualSize().width()),
|
||||
QString::number(scr->virtualSize().height())));
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
class Settings;
|
||||
|
||||
class SettingsNotifications : public SettingsPanel {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SettingsNotifications(Settings* settings, QWidget* parent = nullptr);
|
||||
@ -19,6 +19,9 @@ class SettingsNotifications : public SettingsPanel {
|
||||
virtual void loadSettings();
|
||||
virtual void saveSettings();
|
||||
|
||||
private slots:
|
||||
void showScreenInfo(int index);
|
||||
|
||||
private:
|
||||
Ui::SettingsNotifications m_ui;
|
||||
};
|
||||
|
@ -45,9 +45,6 @@
|
||||
<property name="text">
|
||||
<string>Native notifications (tray icon must be enabled)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
@ -55,6 +52,9 @@
|
||||
<property name="text">
|
||||
<string>Custom notifications</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
@ -76,6 +76,27 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="m_cbCustomNotificationsPosition"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="m_sbScreen">
|
||||
<property name="value">
|
||||
<number>99</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="m_lblScreenInfo">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -134,7 +134,7 @@ PreparedHtml TextBrowserViewer::prepareHtmlForMessage(const QList<Message>& mess
|
||||
html.m_html += is_plain ? Qt::convertFromPlainText(message.m_contents, Qt::WhiteSpaceMode::WhiteSpaceNormal)
|
||||
: message.m_contents;
|
||||
|
||||
static QRegularExpression img_tag_rgx("\\<img[^\\>]*src\\s*=\\s*[\"\']([^\"\']*)[\"\'][^\\>]*\\>",
|
||||
static QRegularExpression img_tag_rgx(QSL("\\<img[^\\>]*src\\s*=\\s*[\"\']([^\"\']*)[\"\'][^\\>]*\\>"),
|
||||
QRegularExpression::PatternOption::CaseInsensitiveOption |
|
||||
QRegularExpression::PatternOption::InvertedGreedinessOption);
|
||||
|
||||
|
@ -111,11 +111,13 @@ Application::Application(const QString& id, int& argc, char** argv, const QStrin
|
||||
m_downloadManager = nullptr;
|
||||
m_notifications = new NotificationFactory(this);
|
||||
m_toastNotifications =
|
||||
new ToastNotificationsManager(settings()
|
||||
->value(GROUP(GUI), SETTING(GUI::ToastNotificationsPosition))
|
||||
.value<ToastNotificationsManager::NotificationPosition>(),
|
||||
settings()->value(GROUP(GUI), SETTING(GUI::ToastNotificationsScreen)).toInt(),
|
||||
this);
|
||||
settings()->value(GROUP(GUI), SETTING(GUI::UseToastNotifications)).toBool()
|
||||
? new ToastNotificationsManager(settings()
|
||||
->value(GROUP(GUI), SETTING(GUI::ToastNotificationsPosition))
|
||||
.value<ToastNotificationsManager::NotificationPosition>(),
|
||||
settings()->value(GROUP(GUI), SETTING(GUI::ToastNotificationsScreen)).toInt(),
|
||||
this)
|
||||
: nullptr;
|
||||
m_shouldRestart = false;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
@ -695,22 +697,26 @@ void Application::showGuiMessageCore(Notification::Event event,
|
||||
GuiMessageDestination dest,
|
||||
const GuiAction& action,
|
||||
QWidget* parent) {
|
||||
m_toastNotifications->showNotification(event, msg, action);
|
||||
return;
|
||||
|
||||
if (m_notifications->areNotificationsEnabled()) {
|
||||
auto notification = m_notifications->notificationForEvent(event);
|
||||
|
||||
notification.playSound(this);
|
||||
|
||||
if (SystemTrayIcon::isSystemTrayDesired() && SystemTrayIcon::isSystemTrayAreaAvailable() &&
|
||||
notification.balloonEnabled() && dest.m_tray) {
|
||||
trayIcon()->showMessage(msg.m_title.simplified().isEmpty() ? Notification::nameForEvent(notification.event())
|
||||
: msg.m_title,
|
||||
msg.m_message,
|
||||
msg.m_type,
|
||||
TRAY_ICON_BUBBLE_TIMEOUT,
|
||||
std::move(action.m_action));
|
||||
if (notification.balloonEnabled() && dest.m_tray) {
|
||||
if (m_toastNotifications != nullptr) {
|
||||
// Toasts are enabled.
|
||||
m_toastNotifications->showNotification(event, msg, action);
|
||||
}
|
||||
else if (SystemTrayIcon::isSystemTrayDesired() && SystemTrayIcon::isSystemTrayAreaAvailable()) {
|
||||
// Use tray icon balloons (which are implemented as native notifications on most systems.
|
||||
trayIcon()->showMessage(msg.m_title.simplified().isEmpty() ? Notification::nameForEvent(notification.event())
|
||||
: msg.m_title,
|
||||
msg.m_message,
|
||||
msg.m_type,
|
||||
TRAY_ICON_BUBBLE_TIMEOUT,
|
||||
std::move(action.m_action));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -999,15 +1005,24 @@ void Application::onFeedUpdatesProgress(const Feed* feed, int current, int total
|
||||
}
|
||||
|
||||
void Application::onFeedUpdatesFinished(const FeedDownloadResults& results) {
|
||||
auto fds = results.updatedFeeds();
|
||||
bool some_unquiet_feed = boolinq::from(fds).any([](const QPair<Feed*, int>& fd) {
|
||||
return !fd.first->isQuiet();
|
||||
auto fds = results.updatedFeeds().keys();
|
||||
bool some_unquiet_feed = boolinq::from(fds).any([](Feed* fd) {
|
||||
return !fd->isQuiet();
|
||||
});
|
||||
|
||||
if (some_unquiet_feed) {
|
||||
// Now, inform about results via GUI message/notification.
|
||||
qApp->showGuiMessage(Notification::Event::NewUnreadArticlesFetched,
|
||||
{tr("Unread articles fetched"), results.overview(10), QSystemTrayIcon::MessageIcon::NoIcon});
|
||||
GuiMessage msg = {tr("Unread articles fetched"), QString(), QSystemTrayIcon::MessageIcon::NoIcon};
|
||||
|
||||
if (m_toastNotifications != nullptr) {
|
||||
// Show custom and richer overview of updated feeds and articles.
|
||||
msg.m_feedFetchResults = results;
|
||||
}
|
||||
else {
|
||||
// Show simpler overview of updated feeds.
|
||||
msg.m_message = results.overview(10);
|
||||
}
|
||||
|
||||
qApp->showGuiMessage(Notification::Event::NewUnreadArticlesFetched, msg);
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -60,6 +60,7 @@ struct GuiMessage {
|
||||
QString m_title;
|
||||
QString m_message;
|
||||
QSystemTrayIcon::MessageIcon m_type;
|
||||
FeedDownloadResults m_feedFetchResults;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(GuiMessage)
|
||||
|
@ -255,19 +255,6 @@ void FeedReader::removeMessageFilterToFeedAssignment(Feed* feed, MessageFilter*
|
||||
}
|
||||
|
||||
void FeedReader::updateAllFeeds() {
|
||||
qApp
|
||||
->showGuiMessage(Notification::Event::GeneralEvent,
|
||||
GuiMessage(QDateTime::currentDateTime().toString(),
|
||||
"Quisque ullamcorper ut purus nec tempus. Vivamus eros dolor, sagittis ultrices augue "
|
||||
"ut, posuere fringilla lorem. Donec posuere, enim sit amet fermentum dignissim, tellus "
|
||||
"lectus laoreet lectus, vestibulum laoreet felis tortor eget nunc. Curabitur sagittis "
|
||||
"quam in scelerisque placerat. Vivamus vel porta tortor. Vivamus nec volutpat sem",
|
||||
QSystemTrayIcon::MessageIcon::Information),
|
||||
GuiMessageDestination(),
|
||||
GuiAction("test", []() {
|
||||
qDebugNN << "aa";
|
||||
}));
|
||||
|
||||
updateFeeds(m_feedsModel->rootItem()->getSubTreeFeeds());
|
||||
}
|
||||
|
||||
|
@ -1110,8 +1110,8 @@ ServiceRoot::LabelOperation operator&(ServiceRoot::LabelOperation lhs, ServiceRo
|
||||
return static_cast<ServiceRoot::LabelOperation>(static_cast<char>(lhs) & static_cast<char>(rhs));
|
||||
}
|
||||
|
||||
QPair<int, int> ServiceRoot::updateMessages(QList<Message>& messages, Feed* feed, bool force_update, QMutex* db_mutex) {
|
||||
QPair<int, int> updated_messages = {0, 0};
|
||||
UpdatedArticles ServiceRoot::updateMessages(QList<Message>& messages, Feed* feed, bool force_update, QMutex* db_mutex) {
|
||||
UpdatedArticles updated_messages;
|
||||
|
||||
if (messages.isEmpty()) {
|
||||
qDebugNN << "No messages to be updated/added in DB for feed" << QUOTE_W_SPACE_DOT(feed->customId());
|
||||
@ -1125,7 +1125,7 @@ QPair<int, int> ServiceRoot::updateMessages(QList<Message>& messages, Feed* feed
|
||||
|
||||
updated_messages = DatabaseQueries::updateMessages(database, messages, feed, force_update, db_mutex, &ok);
|
||||
|
||||
if (updated_messages.first > 0 || updated_messages.second > 0) {
|
||||
if (!updated_messages.m_unread.isEmpty() || !updated_messages.m_all.isEmpty()) {
|
||||
QMutexLocker lck(db_mutex);
|
||||
|
||||
// Something was added or updated in the DB, update numbers.
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "services/abstract/rootitem.h"
|
||||
|
||||
#include "core/message.h"
|
||||
#include "core/messagefilter.h"
|
||||
#include "definitions/typedefs.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
@ -206,7 +205,7 @@ class ServiceRoot : public RootItem {
|
||||
void completelyRemoveAllData();
|
||||
|
||||
// Returns counts of updated messages <unread, all>.
|
||||
QPair<int, int> updateMessages(QList<Message>& messages, Feed* feed, bool force_update, QMutex* db_mutex);
|
||||
UpdatedArticles updateMessages(QList<Message>& messages, Feed* feed, bool force_update, QMutex* db_mutex);
|
||||
|
||||
QIcon feedIconForMessage(const QString& feed_custom_id) const;
|
||||
|
||||
|
@ -418,7 +418,7 @@ QList<Message> FeedlyNetwork::decodeStreamContents(const QByteArray& stream_cont
|
||||
Message message;
|
||||
|
||||
message.m_feedId = entry_obj[QSL("origin")].toObject()[QSL("streamId")].toString();
|
||||
message.m_title = qApp->web()->stripTags(entry_obj[QSL("title")].toString());
|
||||
message.m_title = entry_obj[QSL("title")].toString();
|
||||
message.m_author = entry_obj[QSL("author")].toString();
|
||||
message.m_contents = entry_obj[QSL("content")].toObject()[QSL("content")].toString();
|
||||
message.m_rawContents = QJsonDocument(entry_obj).toJson(QJsonDocument::JsonFormat::Compact);
|
||||
|
@ -957,8 +957,8 @@ QList<Message> GreaderNetwork::decodeStreamContents(ServiceRoot* root,
|
||||
auto message_obj = obj.toObject();
|
||||
Message message;
|
||||
|
||||
message.m_title = qApp->web()->unescapeHtml(message_obj[QSL("title")].toString());
|
||||
message.m_author = qApp->web()->unescapeHtml(message_obj[QSL("author")].toString());
|
||||
message.m_title = message_obj[QSL("title")].toString();
|
||||
message.m_author = message_obj[QSL("author")].toString();
|
||||
message.m_created = QDateTime::fromSecsSinceEpoch(message_obj[QSL("published")].toInt(), Qt::TimeSpec::UTC);
|
||||
message.m_createdFromFeed = true;
|
||||
message.m_customId = message_obj[QSL("id")].toString();
|
||||
|
@ -100,9 +100,9 @@ QList<Message> FeedParser::messages() {
|
||||
Message new_message;
|
||||
|
||||
// Fill available data.
|
||||
new_message.m_title = qApp->web()->stripTags(qApp->web()->unescapeHtml(xmlMessageTitle(message_item)));
|
||||
new_message.m_title = xmlMessageTitle(message_item);
|
||||
new_message.m_contents = xmlMessageDescription(message_item);
|
||||
new_message.m_author = qApp->web()->stripTags(qApp->web()->unescapeHtml(xmlMessageAuthor(message_item)));
|
||||
new_message.m_author = xmlMessageAuthor(message_item);
|
||||
new_message.m_url = xmlMessageUrl(message_item);
|
||||
new_message.m_created = xmlMessageDateCreated(message_item);
|
||||
new_message.m_customId = xmlMessageId(message_item);
|
||||
@ -128,9 +128,9 @@ QList<Message> FeedParser::messages() {
|
||||
Message new_message;
|
||||
|
||||
// Fill available data.
|
||||
new_message.m_title = qApp->web()->stripTags(qApp->web()->unescapeHtml(jsonMessageTitle(message_item)));
|
||||
new_message.m_title = jsonMessageTitle(message_item);
|
||||
new_message.m_contents = jsonMessageDescription(message_item);
|
||||
new_message.m_author = qApp->web()->stripTags(qApp->web()->unescapeHtml(jsonMessageAuthor(message_item)));
|
||||
new_message.m_author = jsonMessageAuthor(message_item);
|
||||
new_message.m_url = jsonMessageUrl(message_item);
|
||||
new_message.m_created = jsonMessageDateCreated(message_item);
|
||||
new_message.m_customId = jsonMessageId(message_item);
|
||||
|
Loading…
x
Reference in New Issue
Block a user