initial fix for #468
This commit is contained in:
parent
92c00c0c8a
commit
6baa539480
@ -37,6 +37,8 @@ set(SOURCES
|
||||
database/sqlitedriver.h
|
||||
definitions/definitions.h
|
||||
definitions/typedefs.h
|
||||
definitions/globals.cpp
|
||||
definitions/globals.h
|
||||
dynamic-shortcuts/dynamicshortcuts.cpp
|
||||
dynamic-shortcuts/dynamicshortcuts.h
|
||||
dynamic-shortcuts/dynamicshortcutswidget.cpp
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "core/messagesmodel.h"
|
||||
#include "core/messagesmodelcache.h"
|
||||
#include "definitions/globals.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/regexfactory.h"
|
||||
#include "miscellaneous/settings.h"
|
||||
@ -14,6 +15,8 @@ MessagesProxyModel::MessagesProxyModel(MessagesModel* source_model, QObject* par
|
||||
: QSortFilterProxyModel(parent), m_sourceModel(source_model), m_filter(MessageListFilter::NoFiltering) {
|
||||
setObjectName(QSL("MessagesProxyModel"));
|
||||
|
||||
initializeFilters();
|
||||
|
||||
setSortRole(Qt::ItemDataRole::EditRole);
|
||||
setSortCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
|
||||
|
||||
@ -28,6 +31,82 @@ MessagesProxyModel::~MessagesProxyModel() {
|
||||
qDebugNN << LOGSEC_MESSAGEMODEL << "Destroying MessagesProxyModel instance.";
|
||||
}
|
||||
|
||||
void MessagesProxyModel::initializeFilters() {
|
||||
m_filters[MessageListFilter::ShowUnread] = [](const Message& msg) {
|
||||
return !msg.m_isRead;
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowImportant] = [](const Message& msg) {
|
||||
return msg.m_isImportant;
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowToday] = [](const Message& msg) {
|
||||
const QDateTime current_dt = QDateTime::currentDateTime();
|
||||
const QDate current_d = current_dt.date();
|
||||
|
||||
return current_d.startOfDay() <= msg.m_created && msg.m_created <= current_d.endOfDay();
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowYesterday] = [](const Message& msg) {
|
||||
const QDateTime current_dt = QDateTime::currentDateTime();
|
||||
const QDate current_d = current_dt.date();
|
||||
|
||||
return current_d.addDays(-1).startOfDay() <= msg.m_created && msg.m_created <= current_d.addDays(-1).endOfDay();
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowLast24Hours] = [](const Message& msg) {
|
||||
const QDateTime current_dt = QDateTime::currentDateTime();
|
||||
|
||||
return current_dt.addSecs(-24 * 60 * 60) <= msg.m_created && msg.m_created <= current_dt;
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowLast48Hours] = [](const Message& msg) {
|
||||
const QDateTime current_dt = QDateTime::currentDateTime();
|
||||
|
||||
return current_dt.addSecs(-48 * 60 * 60) <= msg.m_created && msg.m_created <= current_dt;
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowThisWeek] = [](const Message& msg) {
|
||||
const QDateTime current_dt = QDateTime::currentDateTime();
|
||||
const QDate current_d = current_dt.date();
|
||||
|
||||
return current_d.year() == msg.m_created.date().year() &&
|
||||
current_d.weekNumber() == msg.m_created.date().weekNumber();
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowLastWeek] = [](const Message& msg) {
|
||||
const QDateTime current_dt = QDateTime::currentDateTime();
|
||||
const QDate current_d = current_dt.date();
|
||||
|
||||
return current_d.addDays(-7).year() == msg.m_created.date().year() &&
|
||||
current_d.addDays(-7).weekNumber() == msg.m_created.date().weekNumber();
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowOnlyWithAttachments] = [](const Message& msg) {
|
||||
return msg.m_enclosures.size() > 0;
|
||||
};
|
||||
|
||||
m_filters[MessageListFilter::ShowOnlyWithScore] = [](const Message& msg) {
|
||||
return msg.m_score > MSG_SCORE_MIN;
|
||||
};
|
||||
|
||||
m_filterKeys = m_filters.keys();
|
||||
}
|
||||
|
||||
bool MessagesProxyModel::filterAcceptsMessage(const Message& msg) const {
|
||||
if (m_filter == MessageListFilter::NoFiltering) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (MessageListFilter val : m_filterKeys) {
|
||||
if (Globals::hasFlag(m_filter, val) && m_filters[val](msg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex MessagesProxyModel::getNextPreviousImportantItemIndex(int default_row) {
|
||||
const bool started_from_zero = default_row == 0;
|
||||
QModelIndex next_index = getNextImportantItemIndex(default_row, rowCount() - 1);
|
||||
@ -95,76 +174,7 @@ bool MessagesProxyModel::lessThan(const QModelIndex& left, const QModelIndex& ri
|
||||
Q_UNUSED(left)
|
||||
Q_UNUSED(right)
|
||||
|
||||
// NOTE: Comparisons are done by SQL servers itself, not client-side.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MessagesProxyModel::filterAcceptsMessage(const Message& current_message) const {
|
||||
switch (m_filter) {
|
||||
case MessageListFilter::NoFiltering:
|
||||
return true;
|
||||
|
||||
case MessageListFilter::ShowUnread:
|
||||
return !current_message.m_isRead;
|
||||
|
||||
case MessageListFilter::ShowImportant:
|
||||
return current_message.m_isImportant;
|
||||
|
||||
case MessageListFilter::ShowToday: {
|
||||
const QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
const QDate currentDate = currentDateTime.date();
|
||||
|
||||
return currentDate.startOfDay() <= current_message.m_created &&
|
||||
current_message.m_created <= currentDate.endOfDay();
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowYesterday: {
|
||||
const QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
const QDate currentDate = currentDateTime.date();
|
||||
|
||||
return currentDate.addDays(-1).startOfDay() <= current_message.m_created &&
|
||||
current_message.m_created <= currentDate.addDays(-1).endOfDay();
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowLast24Hours: {
|
||||
const QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
|
||||
return currentDateTime.addSecs(-24 * 60 * 60) <= current_message.m_created &&
|
||||
current_message.m_created <= currentDateTime;
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowLast48Hours: {
|
||||
const QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
|
||||
return currentDateTime.addSecs(-48 * 60 * 60) <= current_message.m_created &&
|
||||
current_message.m_created <= currentDateTime;
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowThisWeek: {
|
||||
const QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
const QDate currentDate = currentDateTime.date();
|
||||
|
||||
return currentDate.year() == current_message.m_created.date().year() &&
|
||||
currentDate.weekNumber() == current_message.m_created.date().weekNumber();
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowLastWeek: {
|
||||
const QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
const QDate currentDate = currentDateTime.date();
|
||||
|
||||
return currentDate.addDays(-7).year() == current_message.m_created.date().year() &&
|
||||
currentDate.addDays(-7).weekNumber() == current_message.m_created.date().weekNumber();
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowOnlyWithAttachments: {
|
||||
return current_message.m_enclosures.size() > 0;
|
||||
}
|
||||
|
||||
case MessageListFilter::ShowOnlyWithScore: {
|
||||
return current_message.m_score > MSG_SCORE_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Comparisons are done by SQL server itself, not client-side.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -15,17 +15,17 @@ class MessagesProxyModel : public QSortFilterProxyModel {
|
||||
// Enum which describes basic filtering schemes
|
||||
// for messages.
|
||||
enum class MessageListFilter {
|
||||
NoFiltering = 100,
|
||||
ShowUnread = 101,
|
||||
ShowImportant = 102,
|
||||
ShowToday = 103,
|
||||
ShowYesterday = 104,
|
||||
ShowLast24Hours = 105,
|
||||
ShowLast48Hours = 106,
|
||||
ShowThisWeek = 107,
|
||||
ShowLastWeek = 108,
|
||||
ShowOnlyWithAttachments = 109,
|
||||
ShowOnlyWithScore = 110
|
||||
NoFiltering = 1,
|
||||
ShowUnread = 2,
|
||||
ShowImportant = 4,
|
||||
ShowToday = 8,
|
||||
ShowYesterday = 16,
|
||||
ShowLast24Hours = 32,
|
||||
ShowLast48Hours = 64,
|
||||
ShowThisWeek = 128,
|
||||
ShowLastWeek = 256,
|
||||
ShowOnlyWithAttachments = 512,
|
||||
ShowOnlyWithScore = 1024
|
||||
};
|
||||
|
||||
explicit MessagesProxyModel(MessagesModel* source_model, QObject* parent = nullptr);
|
||||
@ -51,10 +51,12 @@ class MessagesProxyModel : public QSortFilterProxyModel {
|
||||
virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
private:
|
||||
void initializeFilters();
|
||||
|
||||
QModelIndex getNextImportantItemIndex(int default_row, int max_row) const;
|
||||
QModelIndex getNextUnreadItemIndex(int default_row, int max_row) const;
|
||||
|
||||
bool filterAcceptsMessage(const Message& current_message) const;
|
||||
bool filterAcceptsMessage(const Message& msg) const;
|
||||
|
||||
virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
|
||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
|
||||
@ -62,6 +64,8 @@ class MessagesProxyModel : public QSortFilterProxyModel {
|
||||
// Source model pointer.
|
||||
MessagesModel* m_sourceModel;
|
||||
MessageListFilter m_filter;
|
||||
QMap<MessageListFilter, std::function<bool(const Message&)>> m_filters;
|
||||
QList<MessageListFilter> m_filterKeys;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(MessagesProxyModel::MessageListFilter)
|
||||
|
5
src/librssguard/definitions/globals.cpp
Executable file
5
src/librssguard/definitions/globals.cpp
Executable file
@ -0,0 +1,5 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#include "definitions/globals.h"
|
||||
|
||||
Globals::Globals() {}
|
18
src/librssguard/definitions/globals.h
Executable file
18
src/librssguard/definitions/globals.h
Executable file
@ -0,0 +1,18 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef GLOBALS_H
|
||||
#define GLOBALS_H
|
||||
|
||||
class Globals {
|
||||
public:
|
||||
template <typename T> static bool hasFlag(T lhs, T rhs);
|
||||
|
||||
private:
|
||||
Globals();
|
||||
};
|
||||
|
||||
template <typename T> inline bool Globals::hasFlag(T lhs, T rhs) {
|
||||
return (int(lhs) & int(rhs)) == int(rhs);
|
||||
}
|
||||
|
||||
#endif // GLOBALS_H
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "gui/toolbars/messagestoolbar.h"
|
||||
|
||||
#include "3rd-party/boolinq/boolinq.h"
|
||||
#include "definitions/definitions.h"
|
||||
#include "gui/reusable/baselineedit.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
@ -107,16 +108,46 @@ void MessagesToolBar::loadSpecificActions(const QList<QAction*>& actions, bool i
|
||||
|
||||
void MessagesToolBar::handleMessageHighlighterChange(QAction* action) {
|
||||
m_btnMessageHighlighter->setDefaultAction(action);
|
||||
saveToolButtonSelection(HIGHLIGHTER_ACTION_NAME, action);
|
||||
saveToolButtonSelection(HIGHLIGHTER_ACTION_NAME, {action});
|
||||
|
||||
emit messageHighlighterChanged(action->data().value<MessagesModel::MessageHighlighter>());
|
||||
}
|
||||
|
||||
void MessagesToolBar::handleMessageFilterChange(QAction* action) {
|
||||
m_btnMessageFilter->setDefaultAction(action);
|
||||
saveToolButtonSelection(FILTER_ACTION_NAME, action);
|
||||
inline MessagesProxyModel::MessageListFilter operator|(MessagesProxyModel::MessageListFilter a,
|
||||
MessagesProxyModel::MessageListFilter b) {
|
||||
return static_cast<MessagesProxyModel::MessageListFilter>(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
||||
emit messageFilterChanged(action->data().value<MessagesProxyModel::MessageListFilter>());
|
||||
void MessagesToolBar::handleMessageFilterChange(QAction* action) {
|
||||
MessagesProxyModel::MessageListFilter task = action->data().value<MessagesProxyModel::MessageListFilter>();
|
||||
|
||||
m_btnMessageFilter->setDefaultAction(action);
|
||||
|
||||
auto checked_tasks_std = boolinq::from(m_menuMessageFilter->actions())
|
||||
.where([](QAction* act) {
|
||||
return act->isChecked();
|
||||
})
|
||||
.toStdList();
|
||||
|
||||
if (task == MessagesProxyModel::MessageListFilter::NoFiltering) {
|
||||
// Uncheck everything.
|
||||
m_menuMessageFilter->blockSignals(true);
|
||||
|
||||
for (QAction* tsk : checked_tasks_std) {
|
||||
tsk->setChecked(false);
|
||||
}
|
||||
|
||||
m_menuMessageFilter->blockSignals(false);
|
||||
}
|
||||
else {
|
||||
for (QAction* tsk : checked_tasks_std) {
|
||||
task = task | tsk->data().value<MessagesProxyModel::MessageListFilter>();
|
||||
}
|
||||
}
|
||||
|
||||
saveToolButtonSelection(FILTER_ACTION_NAME, FROM_STD_LIST(QList<QAction*>, checked_tasks_std));
|
||||
|
||||
emit messageFilterChanged(task);
|
||||
}
|
||||
|
||||
void MessagesToolBar::initializeSearchBox() {
|
||||
@ -148,6 +179,7 @@ void MessagesToolBar::addActionToMenu(QMenu* menu,
|
||||
const QString& name) {
|
||||
QAction* action = menu->addAction(icon, title);
|
||||
|
||||
action->setCheckable(true);
|
||||
action->setData(value);
|
||||
action->setObjectName(name);
|
||||
}
|
||||
@ -254,13 +286,19 @@ void MessagesToolBar::initializeHighlighter() {
|
||||
connect(m_menuMessageFilter, &QMenu::triggered, this, &MessagesToolBar::handleMessageFilterChange);
|
||||
}
|
||||
|
||||
void MessagesToolBar::saveToolButtonSelection(const QString& button_name, const QAction* action) const {
|
||||
void MessagesToolBar::saveToolButtonSelection(const QString& button_name, const QList<QAction*>& actions) const {
|
||||
QStringList action_names = savedActions();
|
||||
|
||||
auto opts_list = boolinq::from(actions)
|
||||
.select([](const QAction* act) {
|
||||
return act->objectName();
|
||||
})
|
||||
.toStdList();
|
||||
QStringList opts = FROM_STD_LIST(QStringList, opts_list);
|
||||
|
||||
for (QString& action_name : action_names) {
|
||||
if (action_name.startsWith(button_name)) {
|
||||
action_name =
|
||||
button_name + (action->objectName().isEmpty() ? "" : "[" + action->objectName().toStdString() + "]").c_str();
|
||||
action_name = button_name + QSL("[%1]").arg(opts.join(QL1C(';')));
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,14 +310,13 @@ void MessagesToolBar::activateAction(const QString& action_name, QWidgetAction*
|
||||
const int end = action_name.indexOf(']');
|
||||
|
||||
if (start != -1 && end != -1 && end == action_name.length() - 1) {
|
||||
const QString menu_action_name = action_name.chopped(1).right(end - start - 1);
|
||||
auto toolButton = qobject_cast<QToolButton*>(widget_action->defaultWidget());
|
||||
const QStringList menu_action_names = action_name.chopped(1).right(end - start - 1).split(QL1C(';'));
|
||||
auto tool_btn = qobject_cast<QToolButton*>(widget_action->defaultWidget());
|
||||
|
||||
for (QAction* action : toolButton->menu()->actions()) {
|
||||
if (action->objectName() == menu_action_name) {
|
||||
toolButton->setDefaultAction(action);
|
||||
for (QAction* action : tool_btn->menu()->actions()) {
|
||||
if (menu_action_names.contains(action->objectName())) {
|
||||
// tool_btn->setDefaultAction(action);
|
||||
action->trigger();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class MessagesToolBar : public BaseToolBar {
|
||||
void addActionToMenu(QMenu* menu, const QIcon& icon, const QString& title, const QVariant& value, const QString& name);
|
||||
void initializeHighlighter();
|
||||
void activateAction(const QString& action_name, QWidgetAction* widget_action);
|
||||
void saveToolButtonSelection(const QString& button_name, const QAction* action) const;
|
||||
void saveToolButtonSelection(const QString& button_name, const QList<QAction *> &actions) const;
|
||||
|
||||
private:
|
||||
QWidgetAction* m_actionMessageHighlighter;
|
||||
|
Loading…
x
Reference in New Issue
Block a user