make displaying of huge article lists faster due to optimizations in how article list filtering is handled

This commit is contained in:
Martin Rotter 2023-09-05 10:24:37 +02:00
parent c554ef04a8
commit c37eadea07
18 changed files with 98 additions and 77 deletions

View file

@ -6,6 +6,7 @@
#include "database/databasefactory.h" #include "database/databasefactory.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "definitions/globals.h"
#include "services/abstract/labelsnode.h" #include "services/abstract/labelsnode.h"
#include <QRandomGenerator> #include <QRandomGenerator>
@ -41,27 +42,27 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicateCheck attri
QVector<QPair<QString, QVariant>> bind_values; QVector<QPair<QString, QVariant>> bind_values;
// Now we construct the query according to parameter. // Now we construct the query according to parameter.
if ((attribute_check & DuplicateCheck::SameTitle) == DuplicateCheck::SameTitle) { if (Globals::hasFlag(attribute_check, DuplicateCheck::SameTitle)) {
where_clauses.append(QSL("title = :title")); where_clauses.append(QSL("title = :title"));
bind_values.append({QSL(":title"), title()}); bind_values.append({QSL(":title"), title()});
} }
if ((attribute_check & DuplicateCheck::SameUrl) == DuplicateCheck::SameUrl) { if (Globals::hasFlag(attribute_check, DuplicateCheck::SameUrl)) {
where_clauses.append(QSL("url = :url")); where_clauses.append(QSL("url = :url"));
bind_values.append({QSL(":url"), url()}); bind_values.append({QSL(":url"), url()});
} }
if ((attribute_check & DuplicateCheck::SameAuthor) == DuplicateCheck::SameAuthor) { if (Globals::hasFlag(attribute_check, DuplicateCheck::SameAuthor)) {
where_clauses.append(QSL("author = :author")); where_clauses.append(QSL("author = :author"));
bind_values.append({QSL(":author"), author()}); bind_values.append({QSL(":author"), author()});
} }
if ((attribute_check & DuplicateCheck::SameDateCreated) == DuplicateCheck::SameDateCreated) { if (Globals::hasFlag(attribute_check, DuplicateCheck::SameDateCreated)) {
where_clauses.append(QSL("date_created = :date_created")); where_clauses.append(QSL("date_created = :date_created"));
bind_values.append({QSL(":date_created"), created().toMSecsSinceEpoch()}); bind_values.append({QSL(":date_created"), created().toMSecsSinceEpoch()});
} }
if ((attribute_check & DuplicateCheck::SameCustomId) == DuplicateCheck::SameCustomId) { if (Globals::hasFlag(attribute_check, DuplicateCheck::SameCustomId)) {
where_clauses.append(QSL("custom_id = :custom_id")); where_clauses.append(QSL("custom_id = :custom_id"));
bind_values.append({QSL(":custom_id"), customId()}); bind_values.append({QSL(":custom_id"), customId()});
} }
@ -76,7 +77,7 @@ bool MessageObject::isDuplicateWithAttribute(MessageObject::DuplicateCheck attri
bind_values.append({QSL(":id"), QString::number(m_message->m_id)}); bind_values.append({QSL(":id"), QString::number(m_message->m_id)});
} }
if ((attribute_check & DuplicateCheck::AllFeedsSameAccount) != DuplicateCheck::AllFeedsSameAccount) { if (!Globals::hasFlag(attribute_check, DuplicateCheck::AllFeedsSameAccount)) {
// Limit to current feed. // Limit to current feed.
where_clauses.append(QSL("feed = :feed")); where_clauses.append(QSL("feed = :feed"));
bind_values.append({QSL(":feed"), feedCustomId()}); bind_values.append({QSL(":feed"), feedCustomId()});
@ -177,8 +178,7 @@ QString MessageObject::createLabelId(const QString& title, const QString& hex_co
return lbl_id; return lbl_id;
} }
if ((m_account->supportedLabelOperations() & ServiceRoot::LabelOperation::Adding) != if (!Globals::hasFlag(m_account->supportedLabelOperations(), ServiceRoot::LabelOperation::Adding)) {
ServiceRoot::LabelOperation::Adding) {
qWarningNN << LOGSEC_CORE << "This account does not support creating labels."; qWarningNN << LOGSEC_CORE << "This account does not support creating labels.";
return nullptr; return nullptr;
} }

View file

@ -163,12 +163,4 @@ class MessageObject : public QObject {
bool m_runningAfterFetching; bool m_runningAfterFetching;
}; };
inline MessageObject::DuplicateCheck operator|(MessageObject::DuplicateCheck lhs, MessageObject::DuplicateCheck rhs) {
return static_cast<MessageObject::DuplicateCheck>(int(lhs) | int(rhs));
}
inline MessageObject::DuplicateCheck operator&(MessageObject::DuplicateCheck lhs, MessageObject::DuplicateCheck rhs) {
return static_cast<MessageObject::DuplicateCheck>(int(lhs) & int(rhs));
}
#endif // MESSAGEOBJECT_H #endif // MESSAGEOBJECT_H

View file

@ -579,8 +579,8 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
return dta.toInt() == 1 ? m_favoriteIcon : QVariant(); return dta.toInt() == 1 ? m_favoriteIcon : QVariant();
} }
else if (index_column == MSG_DB_HAS_ENCLOSURES) { else if (index_column == MSG_DB_HAS_ENCLOSURES) {
QModelIndex idx_important = index(idx.row(), MSG_DB_HAS_ENCLOSURES); QModelIndex idx_enc = index(idx.row(), MSG_DB_HAS_ENCLOSURES);
QVariant dta = QSqlQueryModel::data(idx_important); QVariant dta = QSqlQueryModel::data(idx_enc);
return dta.toBool() ? m_enclosuresIcon : QVariant(); return dta.toBool() ? m_enclosuresIcon : QVariant();
} }

View file

@ -4,6 +4,7 @@
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "definitions/globals.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
MessagesModelSqlLayer::MessagesModelSqlLayer() MessagesModelSqlLayer::MessagesModelSqlLayer()
@ -44,8 +45,8 @@ MessagesModelSqlLayer::MessagesModelSqlLayer()
void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting) { void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order, bool ignore_multicolumn_sorting) {
int existing = m_sortColumns.indexOf(column); int existing = m_sortColumns.indexOf(column);
bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & Qt::KeyboardModifier::ControlModifier) == bool is_ctrl_pressed =
Qt::KeyboardModifier::ControlModifier; Globals::hasFlag(QApplication::queryKeyboardModifiers(), Qt::KeyboardModifier::ControlModifier);
if (existing >= 0) { if (existing >= 0) {
m_sortColumns.removeAt(existing); m_sortColumns.removeAt(existing);

View file

@ -6,6 +6,7 @@
#include "core/messagesmodelcache.h" #include "core/messagesmodelcache.h"
#include "definitions/globals.h" #include "definitions/globals.h"
#include "miscellaneous/regexfactory.h" #include "miscellaneous/regexfactory.h"
#include "miscellaneous/textfactory.h"
#include <QTimer> #include <QTimer>
@ -30,74 +31,96 @@ MessagesProxyModel::~MessagesProxyModel() {
} }
void MessagesProxyModel::initializeFilters() { void MessagesProxyModel::initializeFilters() {
m_filters[MessageListFilter::ShowUnread] = [](const Message& msg) { m_filters[MessageListFilter::ShowUnread] = [this](int msg_row_index) {
return !msg.m_isRead; return !m_sourceModel->data(msg_row_index, MSG_DB_READ_INDEX, Qt::ItemDataRole::EditRole).toBool();
}; };
m_filters[MessageListFilter::ShowImportant] = [](const Message& msg) { m_filters[MessageListFilter::ShowImportant] = [this](int msg_row_index) {
return msg.m_isImportant; return m_sourceModel->data(msg_row_index, MSG_DB_IMPORTANT_INDEX, Qt::ItemDataRole::EditRole).toBool();
}; };
m_filters[MessageListFilter::ShowToday] = [](const Message& msg) { m_filters[MessageListFilter::ShowToday] = [this](int msg_row_index) {
const QDateTime current_dt = QDateTime::currentDateTime(); const QDateTime current_dt = QDateTime::currentDateTime();
const QDate current_d = current_dt.date(); const QDate current_d = current_dt.date();
const QDateTime msg_created =
TextFactory::parseDateTime(m_sourceModel->data(msg_row_index, MSG_DB_DCREATED_INDEX, Qt::ItemDataRole::EditRole)
.value<qint64>());
return current_d.startOfDay() <= msg.m_created && msg.m_created <= current_d.endOfDay(); return current_d.startOfDay() <= msg_created && msg_created <= current_d.endOfDay();
}; };
m_filters[MessageListFilter::ShowYesterday] = [](const Message& msg) { m_filters[MessageListFilter::ShowYesterday] = [this](int msg_row_index) {
const QDateTime current_dt = QDateTime::currentDateTime(); const QDateTime current_dt = QDateTime::currentDateTime();
const QDate current_d = current_dt.date(); const QDate current_d = current_dt.date();
const QDateTime msg_created =
TextFactory::parseDateTime(m_sourceModel->data(msg_row_index, MSG_DB_DCREATED_INDEX, Qt::ItemDataRole::EditRole)
.value<qint64>());
return current_d.addDays(-1).startOfDay() <= msg.m_created && msg.m_created <= current_d.addDays(-1).endOfDay(); return current_d.addDays(-1).startOfDay() <= msg_created && msg_created <= current_d.addDays(-1).endOfDay();
}; };
m_filters[MessageListFilter::ShowLast24Hours] = [](const Message& msg) { m_filters[MessageListFilter::ShowLast24Hours] = [this](int msg_row_index) {
const QDateTime current_dt = QDateTime::currentDateTime(); const QDateTime current_dt = QDateTime::currentDateTime();
const QDateTime msg_created =
TextFactory::parseDateTime(m_sourceModel->data(msg_row_index, MSG_DB_DCREATED_INDEX, Qt::ItemDataRole::EditRole)
.value<qint64>());
return current_dt.addSecs(-24 * 60 * 60) <= msg.m_created && msg.m_created <= current_dt; return current_dt.addSecs(-24 * 60 * 60) <= msg_created && msg_created <= current_dt;
}; };
m_filters[MessageListFilter::ShowLast48Hours] = [](const Message& msg) { m_filters[MessageListFilter::ShowLast48Hours] = [this](int msg_row_index) {
const QDateTime current_dt = QDateTime::currentDateTime(); const QDateTime current_dt = QDateTime::currentDateTime();
const QDateTime msg_created =
TextFactory::parseDateTime(m_sourceModel->data(msg_row_index, MSG_DB_DCREATED_INDEX, Qt::ItemDataRole::EditRole)
.value<qint64>());
return current_dt.addSecs(-48 * 60 * 60) <= msg.m_created && msg.m_created <= current_dt; return current_dt.addSecs(-48 * 60 * 60) <= msg_created && msg_created <= current_dt;
}; };
m_filters[MessageListFilter::ShowThisWeek] = [](const Message& msg) { m_filters[MessageListFilter::ShowThisWeek] = [this](int msg_row_index) {
const QDateTime current_dt = QDateTime::currentDateTime(); const QDateTime current_dt = QDateTime::currentDateTime();
const QDate current_d = current_dt.date(); const QDate current_d = current_dt.date();
const QDateTime msg_created =
TextFactory::parseDateTime(m_sourceModel->data(msg_row_index, MSG_DB_DCREATED_INDEX, Qt::ItemDataRole::EditRole)
.value<qint64>());
return current_d.year() == msg.m_created.date().year() && return current_d.year() == msg_created.date().year() && current_d.weekNumber() == msg_created.date().weekNumber();
current_d.weekNumber() == msg.m_created.date().weekNumber();
}; };
m_filters[MessageListFilter::ShowLastWeek] = [](const Message& msg) { m_filters[MessageListFilter::ShowLastWeek] = [this](int msg_row_index) {
const QDateTime current_dt = QDateTime::currentDateTime(); const QDateTime current_dt = QDateTime::currentDateTime();
const QDate current_d = current_dt.date(); const QDate current_d = current_dt.date();
const QDateTime msg_created =
TextFactory::parseDateTime(m_sourceModel->data(msg_row_index, MSG_DB_DCREATED_INDEX, Qt::ItemDataRole::EditRole)
.value<qint64>());
return current_d.addDays(-7).year() == msg.m_created.date().year() && return current_d.addDays(-7).year() == msg_created.date().year() &&
current_d.addDays(-7).weekNumber() == msg.m_created.date().weekNumber(); current_d.addDays(-7).weekNumber() == msg_created.date().weekNumber();
}; };
m_filters[MessageListFilter::ShowOnlyWithAttachments] = [](const Message& msg) { m_filters[MessageListFilter::ShowOnlyWithAttachments] = [this](int msg_row_index) {
return msg.m_enclosures.size() > 0; const bool msg_has_enclosures =
m_sourceModel->data(msg_row_index, MSG_DB_HAS_ENCLOSURES, Qt::ItemDataRole::EditRole).toBool();
return msg_has_enclosures;
}; };
m_filters[MessageListFilter::ShowOnlyWithScore] = [](const Message& msg) { m_filters[MessageListFilter::ShowOnlyWithScore] = [this](int msg_row_index) {
return msg.m_score > MSG_SCORE_MIN; const int msg_score = m_sourceModel->data(msg_row_index, MSG_DB_SCORE_INDEX, Qt::ItemDataRole::EditRole).toDouble();
return msg_score > MSG_SCORE_MIN;
}; };
m_filterKeys = m_filters.keys(); m_filterKeys = m_filters.keys();
} }
bool MessagesProxyModel::filterAcceptsMessage(const Message& msg) const { bool MessagesProxyModel::filterAcceptsMessage(int msg_row_index) const {
if (m_filter == MessageListFilter::NoFiltering) { if (m_filter == MessageListFilter::NoFiltering) {
return true; return true;
} }
for (MessageListFilter val : m_filterKeys) { for (MessageListFilter val : m_filterKeys) {
if (Globals::hasFlag(m_filter, val) && m_filters[val](msg)) { if (Globals::hasFlag(m_filter, val) && m_filters[val](msg_row_index)) {
return true; return true;
} }
} }
@ -184,8 +207,7 @@ bool MessagesProxyModel::filterAcceptsRow(int source_row, const QModelIndex& sou
// otherwise they would just disappear from the list for example when batch marked as read // otherwise they would just disappear from the list for example when batch marked as read
// which is distracting. // which is distracting.
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) && return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent) &&
(m_sourceModel->cache()->containsData(source_row) || (m_sourceModel->cache()->containsData(source_row) || filterAcceptsMessage(source_row));
filterAcceptsMessage(m_sourceModel->messageAt(source_row)));
} }
void MessagesProxyModel::setMessageListFilter(MessageListFilter filter) { void MessagesProxyModel::setMessageListFilter(MessageListFilter filter) {
@ -216,7 +238,8 @@ QModelIndexList MessagesProxyModel::match(const QModelIndex& start,
QModelIndexList result; QModelIndexList result;
const int match_type = flags & 0x0F; const int match_type = flags & 0x0F;
const Qt::CaseSensitivity case_sensitivity = Qt::CaseSensitivity::CaseInsensitive; const Qt::CaseSensitivity case_sensitivity = Qt::CaseSensitivity::CaseInsensitive;
const bool wrap = (flags & Qt::MatchFlag::MatchWrap) > 0; const bool wrap = Globals::hasFlag(flags, Qt::MatchFlag::MatchWrap);
;
const bool all_hits = (hits == -1); const bool all_hits = (hits == -1);
QString entered_text; QString entered_text;
int from = start.row(); int from = start.row();

View file

@ -56,7 +56,7 @@ class MessagesProxyModel : public QSortFilterProxyModel {
QModelIndex getNextImportantItemIndex(int default_row, int max_row) const; QModelIndex getNextImportantItemIndex(int default_row, int max_row) const;
QModelIndex getNextUnreadItemIndex(int default_row, int max_row) const; QModelIndex getNextUnreadItemIndex(int default_row, int max_row) const;
bool filterAcceptsMessage(const Message& msg) const; bool filterAcceptsMessage(int msg_row_index) const;
virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const; virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
@ -64,7 +64,7 @@ class MessagesProxyModel : public QSortFilterProxyModel {
// Source model pointer. // Source model pointer.
MessagesModel* m_sourceModel; MessagesModel* m_sourceModel;
MessageListFilter m_filter; MessageListFilter m_filter;
QMap<MessageListFilter, std::function<bool(const Message&)>> m_filters; QMap<MessageListFilter, std::function<bool(int)>> m_filters;
QList<MessageListFilter> m_filterKeys; QList<MessageListFilter> m_filterKeys;
}; };

View file

@ -3,6 +3,7 @@
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "definitions/globals.h"
#include "exceptions/applicationexception.h" #include "exceptions/applicationexception.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
@ -1710,9 +1711,8 @@ QPair<int, int> DatabaseQueries::updateMessages(const QSqlDatabase& db,
} }
} }
const bool uses_online_labels = const bool uses_online_labels = Globals::hasFlag(feed->getParentServiceRoot()->supportedLabelOperations(),
(feed->getParentServiceRoot()->supportedLabelOperations() & ServiceRoot::LabelOperation::Synchronised) == ServiceRoot::LabelOperation::Synchronised);
ServiceRoot::LabelOperation::Synchronised;
for (Message& message : messages) { for (Message& message : messages) {
if (!message.m_customId.isEmpty() || message.m_id > 0) { if (!message.m_customId.isEmpty() || message.m_id > 0) {

View file

@ -5,14 +5,16 @@
class Globals { class Globals {
public: public:
template <typename T, typename U> static bool hasFlag(T lhs, U rhs); template <typename T, typename U>
static bool hasFlag(T value, U flag);
private: private:
Globals(); Globals();
}; };
template <typename T, typename U> inline bool Globals::hasFlag(T lhs, U rhs) { template <typename T, typename U>
return (int(lhs) & int(rhs)) == int(rhs); inline bool Globals::hasFlag(T value, U flag) {
return (int(value) & int(flag)) == int(flag);
} }
#endif // GLOBALS_H #endif // GLOBALS_H

View file

@ -3,6 +3,7 @@
#include "gui/dialogs/formmain.h" #include "gui/dialogs/formmain.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "definitions/globals.h"
#include "gui/dialogs/formabout.h" #include "gui/dialogs/formabout.h"
#include "gui/dialogs/formaddaccount.h" #include "gui/dialogs/formaddaccount.h"
#include "gui/dialogs/formbackupdatabasesettings.h" #include "gui/dialogs/formbackupdatabasesettings.h"
@ -1042,8 +1043,8 @@ void FormMain::restoreDatabaseSettings() {
void FormMain::changeEvent(QEvent* event) { void FormMain::changeEvent(QEvent* event) {
switch (event->type()) { switch (event->type()) {
case QEvent::Type::WindowStateChange: { case QEvent::Type::WindowStateChange: {
if ((windowState() & Qt::WindowState::WindowMinimized) == Qt::WindowState::WindowMinimized && if (Globals::hasFlag(windowState(), Qt::WindowState::WindowMinimized) && SystemTrayIcon::isSystemTrayDesired() &&
SystemTrayIcon::isSystemTrayDesired() && SystemTrayIcon::isSystemTrayAreaAvailable() && SystemTrayIcon::isSystemTrayAreaAvailable() &&
qApp->settings()->value(GROUP(GUI), SETTING(GUI::HideMainWindowWhenMinimized)).toBool()) { qApp->settings()->value(GROUP(GUI), SETTING(GUI::HideMainWindowWhenMinimized)).toBool()) {
event->ignore(); event->ignore();

View file

@ -3,6 +3,7 @@
#include "gui/reusable/styleditemdelegatewithoutfocus.h" #include "gui/reusable/styleditemdelegatewithoutfocus.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "definitions/globals.h"
StyledItemDelegateWithoutFocus::StyledItemDelegateWithoutFocus(int height_row, int padding_row, QObject* parent) StyledItemDelegateWithoutFocus::StyledItemDelegateWithoutFocus(int height_row, int padding_row, QObject* parent)
: QStyledItemDelegate(parent), m_rowHeight(height_row), m_rowPadding(padding_row) {} : QStyledItemDelegate(parent), m_rowHeight(height_row), m_rowPadding(padding_row) {}
@ -12,7 +13,7 @@ void StyledItemDelegateWithoutFocus::paint(QPainter* painter,
const QModelIndex& index) const { const QModelIndex& index) const {
QStyleOptionViewItem item_option(option); QStyleOptionViewItem item_option(option);
if ((item_option.state & QStyle::StateFlag::State_HasFocus) == QStyle::StateFlag::State_HasFocus) { if (Globals::hasFlag(item_option.state, QStyle::StateFlag::State_HasFocus)) {
item_option.state = item_option.state ^ QStyle::StateFlag::State_HasFocus; item_option.state = item_option.state ^ QStyle::StateFlag::State_HasFocus;
} }
@ -22,7 +23,7 @@ void StyledItemDelegateWithoutFocus::paint(QPainter* painter,
item_option.direction = Qt::LayoutDirection::RightToLeft; item_option.direction = Qt::LayoutDirection::RightToLeft;
} }
if ((item_option.state & QStyle::StateFlag::State_Selected) == QStyle::StateFlag::State_Selected && if (Globals::hasFlag(item_option.state, QStyle::StateFlag::State_Selected) &&
index.data(Qt::ItemDataRole::ForegroundRole).isValid()) { index.data(Qt::ItemDataRole::ForegroundRole).isValid()) {
item_option.palette.setColor(QPalette::ColorRole::HighlightedText, item_option.palette.setColor(QPalette::ColorRole::HighlightedText,
index.data(HIGHLIGHTED_FOREGROUND_TITLE_ROLE).value<QColor>()); index.data(HIGHLIGHTED_FOREGROUND_TITLE_ROLE).value<QColor>());

View file

@ -3,6 +3,7 @@
#include "gui/tabbar.h" #include "gui/tabbar.h"
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "definitions/globals.h"
#include "gui/reusable/plaintoolbutton.h" #include "gui/reusable/plaintoolbutton.h"
#include "miscellaneous/settings.h" #include "miscellaneous/settings.h"
@ -91,7 +92,7 @@ void TabBar::mousePressEvent(QMouseEvent* event) {
// Check if user clicked tab with middle button. // Check if user clicked tab with middle button.
// NOTE: This needs to be done here because // NOTE: This needs to be done here because
// destination does not know the original event. // destination does not know the original event.
if ((event->button() & Qt::MiddleButton) == Qt::MiddleButton && if (Globals::hasFlag(event->button(), Qt::MouseButton::MiddleButton) &&
qApp->settings()->value(GROUP(GUI), SETTING(GUI::TabCloseMiddleClick)).toBool()) { qApp->settings()->value(GROUP(GUI), SETTING(GUI::TabCloseMiddleClick)).toBool()) {
if (tabType(tab_index) == TabBar::TabType::Closable || tabType(tab_index) == TabBar::TabType::DownloadManager) { if (tabType(tab_index) == TabBar::TabType::Closable || tabType(tab_index) == TabBar::TabType::DownloadManager) {
// This tab is closable, so we can close it. // This tab is closable, so we can close it.
@ -110,7 +111,7 @@ void TabBar::mouseDoubleClickEvent(QMouseEvent* event) {
// Check if user clicked tab with middle button. // Check if user clicked tab with middle button.
// NOTE: This needs to be done here because // NOTE: This needs to be done here because
// destination does not know the original event. // destination does not know the original event.
if ((event->button() & Qt::LeftButton) == Qt::LeftButton && if (Globals::hasFlag(event->button(), Qt::MouseButton::LeftButton) &&
qApp->settings()->value(GROUP(GUI), SETTING(GUI::TabCloseDoubleClick)).toBool()) { qApp->settings()->value(GROUP(GUI), SETTING(GUI::TabCloseDoubleClick)).toBool()) {
if (int(tabType(tab_index) & (TabBar::TabType::Closable | TabBar::TabType::DownloadManager)) > 0) { if (int(tabType(tab_index) & (TabBar::TabType::Closable | TabBar::TabType::DownloadManager)) > 0) {
// This tab is closable, so we can close it. // This tab is closable, so we can close it.

View file

@ -2,6 +2,7 @@
#include "gui/toolbars/toolbareditor.h" #include "gui/toolbars/toolbareditor.h"
#include "definitions/globals.h"
#include "gui/toolbars/basetoolbar.h" #include "gui/toolbars/basetoolbar.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
@ -144,14 +145,12 @@ bool ToolBarEditor::eventFilter(QObject* object, QEvent* event) {
return true; return true;
} }
else if (key_event->key() == Qt::Key::Key_Down && else if (key_event->key() == Qt::Key::Key_Down &&
(key_event->modifiers() & Qt::KeyboardModifier::ControlModifier) == Globals::hasFlag(key_event->modifiers(), Qt::KeyboardModifier::ControlModifier)) {
Qt::KeyboardModifier::ControlModifier) {
moveActionDown(); moveActionDown();
return true; return true;
} }
else if (key_event->key() == Qt::Key::Key_Up && else if (key_event->key() == Qt::Key::Key_Up &&
(key_event->modifiers() & Qt::KeyboardModifier::ControlModifier) == Globals::hasFlag(key_event->modifiers(), Qt::KeyboardModifier::ControlModifier)) {
Qt::KeyboardModifier::ControlModifier) {
moveActionUp(); moveActionUp();
return true; return true;
} }

View file

@ -2,6 +2,7 @@
#include "gui/webbrowser.h" #include "gui/webbrowser.h"
#include "definitions/globals.h"
#include "gui/dialogs/formmain.h" #include "gui/dialogs/formmain.h"
#include "gui/messagebox.h" #include "gui/messagebox.h"
#include "gui/reusable/discoverfeedsbutton.h" #include "gui/reusable/discoverfeedsbutton.h"
@ -173,7 +174,7 @@ bool WebBrowser::eventFilter(QObject* watched, QEvent* event) {
QWheelEvent* wh_event = static_cast<QWheelEvent*>(event); QWheelEvent* wh_event = static_cast<QWheelEvent*>(event);
// Zoom with mouse. // Zoom with mouse.
if ((wh_event->modifiers() & Qt::KeyboardModifier::ControlModifier) > 0) { if (Globals::hasFlag(wh_event->modifiers(), Qt::KeyboardModifier::ControlModifier)) {
if (wh_event->angleDelta().y() > 0 && m_webView->canZoomIn()) { if (wh_event->angleDelta().y() > 0 && m_webView->canZoomIn()) {
m_webView->zoomIn(); m_webView->zoomIn();
onZoomFactorChanged(); onZoomFactorChanged();

View file

@ -3,6 +3,7 @@
#include "gui/webviewers/qtextbrowser/textbrowserviewer.h" #include "gui/webviewers/qtextbrowser/textbrowserviewer.h"
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "definitions/globals.h"
#include "gui/dialogs/formmain.h" #include "gui/dialogs/formmain.h"
#include "gui/webbrowser.h" #include "gui/webbrowser.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
@ -472,8 +473,8 @@ void TextBrowserViewer::downloadLink() {
void TextBrowserViewer::onAnchorClicked(const QUrl& url) { void TextBrowserViewer::onAnchorClicked(const QUrl& url) {
if (!url.isEmpty()) { if (!url.isEmpty()) {
const QUrl resolved_url = (m_currentUrl.isValid() && url.isRelative()) ? m_currentUrl.resolved(url) : url; const QUrl resolved_url = (m_currentUrl.isValid() && url.isRelative()) ? m_currentUrl.resolved(url) : url;
const bool ctrl_pressed = (QGuiApplication::keyboardModifiers() & Qt::KeyboardModifier::ControlModifier) == const bool ctrl_pressed =
Qt::KeyboardModifier::ControlModifier; Globals::hasFlag(QGuiApplication::keyboardModifiers(), Qt::KeyboardModifier::ControlModifier);
if (ctrl_pressed) { if (ctrl_pressed) {
// Open in new tab. // Open in new tab.

View file

@ -562,7 +562,7 @@ QVariant Skin::colorForModel(SkinEnums::PaletteColors type, bool use_skin_colors
} }
} }
return (use_skin_colors & m_colorPalette.contains(type)) ? m_colorPalette[type] : QVariant(); return (use_skin_colors && m_colorPalette.contains(type)) ? m_colorPalette[type] : QVariant();
} }
QPalette Skin::extractPalette() const { QPalette Skin::extractPalette() const {

View file

@ -4,6 +4,7 @@
#include "database/databasefactory.h" #include "database/databasefactory.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/globals.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "services/abstract/cacheforserviceroot.h" #include "services/abstract/cacheforserviceroot.h"
#include "services/abstract/gui/formaddeditlabel.h" #include "services/abstract/gui/formaddeditlabel.h"
@ -39,8 +40,7 @@ int Label::countOfAllMessages() const {
} }
bool Label::canBeEdited() const { bool Label::canBeEdited() const {
return (getParentServiceRoot()->supportedLabelOperations() & ServiceRoot::LabelOperation::Editing) == return Globals::hasFlag(getParentServiceRoot()->supportedLabelOperations(), ServiceRoot::LabelOperation::Editing);
ServiceRoot::LabelOperation::Editing;
} }
bool Label::editViaGui() { bool Label::editViaGui() {
@ -57,8 +57,7 @@ bool Label::editViaGui() {
} }
bool Label::canBeDeleted() const { bool Label::canBeDeleted() const {
return (getParentServiceRoot()->supportedLabelOperations() & ServiceRoot::LabelOperation::Deleting) == return Globals::hasFlag(getParentServiceRoot()->supportedLabelOperations(), ServiceRoot::LabelOperation::Deleting);
ServiceRoot::LabelOperation::Deleting;
} }
bool Label::deleteViaGui() { bool Label::deleteViaGui() {

View file

@ -4,6 +4,7 @@
#include "database/databasefactory.h" #include "database/databasefactory.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/globals.h"
#include "exceptions/applicationexception.h" #include "exceptions/applicationexception.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
@ -92,8 +93,7 @@ QList<QAction*> LabelsNode::contextMenuFeedsList() {
} }
void LabelsNode::createLabel() { void LabelsNode::createLabel() {
if ((getParentServiceRoot()->supportedLabelOperations() & ServiceRoot::LabelOperation::Adding) == if (Globals::hasFlag(getParentServiceRoot()->supportedLabelOperations(), ServiceRoot::LabelOperation::Adding)) {
ServiceRoot::LabelOperation::Adding) {
FormAddEditLabel frm(qApp->mainFormWidget()); FormAddEditLabel frm(qApp->mainFormWidget());
Label* new_lbl = frm.execForAdd(); Label* new_lbl = frm.execForAdd();

View file

@ -5,6 +5,7 @@
#include "3rd-party/boolinq/boolinq.h" #include "3rd-party/boolinq/boolinq.h"
#include "core/messagesmodel.h" #include "core/messagesmodel.h"
#include "database/databasequeries.h" #include "database/databasequeries.h"
#include "definitions/globals.h"
#include "exceptions/applicationexception.h" #include "exceptions/applicationexception.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
@ -495,8 +496,7 @@ void ServiceRoot::syncIn() {
auto categories_custom_data = storeCustomCategoriesData(); auto categories_custom_data = storeCustomCategoriesData();
// Remove from feeds model, then from SQL but leave messages intact. // Remove from feeds model, then from SQL but leave messages intact.
bool uses_remote_labels = bool uses_remote_labels = Globals::hasFlag(supportedLabelOperations(), LabelOperation::Synchronised);
(supportedLabelOperations() & LabelOperation::Synchronised) == LabelOperation::Synchronised;
// Remove stuff. // Remove stuff.
cleanAllItemsFromModel(uses_remote_labels); cleanAllItemsFromModel(uses_remote_labels);