Skip to content

Commit

Permalink
initial fix for #468
Browse files Browse the repository at this point in the history
  • Loading branch information
martinrotter committed Feb 2, 2023
1 parent 92c00c0 commit 6baa539
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 95 deletions.
2 changes: 2 additions & 0 deletions src/librssguard/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
150 changes: 80 additions & 70 deletions src/librssguard/core/messagesproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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);

Expand All @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
28 changes: 16 additions & 12 deletions src/librssguard/core/messagesproxymodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -51,17 +51,21 @@ 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;

// 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)
Expand Down
5 changes: 5 additions & 0 deletions src/librssguard/definitions/globals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// For license of this file, see <project-root-folder>/LICENSE.md.

#include "definitions/globals.h"

Globals::Globals() {}
18 changes: 18 additions & 0 deletions src/librssguard/definitions/globals.h
Original file line number Diff line number Diff line change
@@ -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
61 changes: 49 additions & 12 deletions src/librssguard/gui/toolbars/messagestoolbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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>());
}

inline MessagesProxyModel::MessageListFilter operator|(MessagesProxyModel::MessageListFilter a,
MessagesProxyModel::MessageListFilter b) {
return static_cast<MessagesProxyModel::MessageListFilter>(static_cast<int>(a) | static_cast<int>(b));
}

void MessagesToolBar::handleMessageFilterChange(QAction* action) {
MessagesProxyModel::MessageListFilter task = action->data().value<MessagesProxyModel::MessageListFilter>();

m_btnMessageFilter->setDefaultAction(action);
saveToolButtonSelection(FILTER_ACTION_NAME, action);

emit messageFilterChanged(action->data().value<MessagesProxyModel::MessageListFilter>());
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() {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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(';')));
}
}

Expand All @@ -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;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librssguard/gui/toolbars/messagestoolbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 6baa539

Please sign in to comment.