Added ability to (de)assign labels to messages.

This commit is contained in:
Martin Rotter 2020-10-17 17:14:51 +02:00
parent e8ea98d3fa
commit 93721ac9e0
7 changed files with 128 additions and 10 deletions

View File

@ -47,7 +47,7 @@ void MessagePreviewer::createConnections() {
MessagePreviewer::MessagePreviewer(QWidget* parent)
: QWidget(parent), m_layout(new QGridLayout(this)), m_toolBar(new QToolBar(this)), m_verticalScrollBarPosition(0.0),
m_separator(nullptr), m_btnLabels(QList<QPair<QToolButton*, QAction*>>()) {
m_separator(nullptr), m_btnLabels(QList<QPair<LabelButton*, QAction*>>()) {
#if defined (USE_WEBENGINE)
m_txtMessage = new WebBrowser(this);
#else
@ -115,6 +115,21 @@ void MessagePreviewer::loadMessage(const Message& message, RootItem* root) {
}
}
void MessagePreviewer::switchLabel(bool assign) {
auto lbl = qobject_cast<LabelButton*>(sender())->label();
if (lbl == nullptr) {
return;
}
if (assign) {
lbl->assignToMessage(m_message);
}
else {
lbl->deassignFromMessage(m_message);
}
}
void MessagePreviewer::markMessageAsRead() {
markMessageAsReadUnread(RootItem::ReadStatus::Read);
}
@ -192,23 +207,34 @@ void MessagePreviewer::updateLabels(bool only_clear) {
if (m_root.data() != nullptr) {
m_separator = m_toolBar->addSeparator();
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
for (auto* label : m_root.data()->getParentServiceRoot()->labelsNode()->labels()) {
QToolButton* btn_label = new QToolButton(this);
LabelButton* btn_label = new LabelButton(this);
btn_label->setLabel(label);
btn_label->setCheckable(true);
btn_label->setIcon(Label::generateIcon(label->color()));
btn_label->setAutoRaise(false);
btn_label->setText(label->title());
btn_label->setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonTextBesideIcon);
btn_label->setChecked(DatabaseQueries::isLabelAssignedToMessage(database, label, m_message));
QAction* act_label = m_toolBar->addWidget(btn_label);
connect(act_label, &QAction::triggered, this, []() {
int a = 5;
});
connect(btn_label, &QToolButton::toggled, this, &MessagePreviewer::switchLabel);
m_btnLabels.append(QPair<QToolButton*, QAction*>(btn_label, act_label));
m_btnLabels.append({ btn_label, act_label });
}
}
}
LabelButton::LabelButton(QWidget* parent) : QToolButton(parent), m_label(nullptr) {}
Label* LabelButton::label() const {
return m_label.data();
}
void LabelButton::setLabel(Label* label) {
m_label = label;
}

View File

@ -3,14 +3,14 @@
#ifndef MESSAGEPREVIEWER_H
#define MESSAGEPREVIEWER_H
#include <QWidget>
#include <QToolButton>
#include "core/message.h"
#include "services/abstract/label.h"
#include "services/abstract/rootitem.h"
#include <QPointer>
class QToolButton;
class QGridLayout;
class QToolBar;
@ -20,6 +20,19 @@ class WebBrowser;
class MessageBrowser;
#endif
class LabelButton : public QToolButton {
Q_OBJECT
public:
explicit LabelButton(QWidget* parent = nullptr);
Label* label() const;
void setLabel(Label* label);
private:
QPointer<Label> m_label;
};
class MessagePreviewer : public QWidget {
Q_OBJECT
@ -38,6 +51,7 @@ class MessagePreviewer : public QWidget {
void loadMessage(const Message& message, RootItem* root);
private slots:
void switchLabel(bool assign);
void markMessageAsRead();
void markMessageAsUnread();
void markMessageAsReadUnread(RootItem::ReadStatus read);
@ -70,7 +84,7 @@ class MessagePreviewer : public QWidget {
QAction* m_actionMarkUnread;
QAction* m_actionSwitchImportance;
QAction* m_separator;
QList<QPair<QToolButton*, QAction*>> m_btnLabels;
QList<QPair<LabelButton*, QAction*>> m_btnLabels;
};
#endif // MESSAGEPREVIEWER_H

View File

@ -152,7 +152,7 @@ void MessagesView::setupAppearance() {
header()->setDefaultSectionSize(MESSAGES_VIEW_DEFAULT_COL);
header()->setMinimumSectionSize(MESSAGES_VIEW_MINIMUM_COL);
header()->setCascadingSectionResizes(false);
header()->setStretchLastSection(false);
header()->setStretchLastSection(true);
}
void MessagesView::focusInEvent(QFocusEvent* event) {

View File

@ -31,6 +31,55 @@
#include <QUrl>
#include <QVariant>
bool DatabaseQueries::isLabelAssignedToMessage(const QSqlDatabase& db, Label* label, const Message& msg) {
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare("SELECT COUNT(*) FROM LabelsInMessages WHERE label = :label AND message = :message AND account_id = :account_id;");
q.bindValue(QSL(":label"), label->customId());
q.bindValue(QSL(":message"), msg.m_customId);
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
q.exec() && q.next();
return q.record().value(0).toInt() > 0;
}
bool DatabaseQueries::deassignLabelFromMessage(const QSqlDatabase& db, Label* label, const Message& msg) {
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare("DELETE FROM LabelsInMessages WHERE label = :label AND message = :message AND account_id = :account_id;");
q.bindValue(QSL(":label"), label->customId());
q.bindValue(QSL(":message"), msg.m_customId);
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
return q.exec();
}
bool DatabaseQueries::assignLabelToMessage(const QSqlDatabase& db, Label* label, const Message& msg) {
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare("DELETE FROM LabelsInMessages WHERE label = :label AND message = :message AND account_id = :account_id;");
q.bindValue(QSL(":label"), label->customId());
q.bindValue(QSL(":message"), msg.m_customId);
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
auto succ = q.exec();
if (succ) {
q.prepare("INSERT INTO LabelsInMessages (label, message, account_id) VALUES (:label, :message, :account_id);");
q.bindValue(QSL(":label"), label->customId());
q.bindValue(QSL(":message"), msg.m_customId);
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
succ = q.exec();
}
return succ;
}
QList<Label*> DatabaseQueries::getLabels(const QSqlDatabase& db, int account_id) {
QList<Label*> labels;
QSqlQuery q(db);
@ -104,6 +153,10 @@ bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int acco
if (res && q.lastInsertId().isValid()) {
label->setId(q.lastInsertId().toInt());
// NOTE: This custom ID in this object will be probably
// overwritten in online-synchronized labels.
label->setCustomId(QString::number(label->id()));
}
// Fixup missing custom IDs.

View File

@ -19,6 +19,9 @@ class DatabaseQueries {
public:
// Label operators.
static bool isLabelAssignedToMessage(const QSqlDatabase& db, Label* label, const Message& msg);
static bool deassignLabelFromMessage(const QSqlDatabase& db, Label* label, const Message& msg);
static bool assignLabelToMessage(const QSqlDatabase& db, Label* label, const Message& msg);
static QList<Label*> getLabels(const QSqlDatabase& db, int account_id);
static bool updateLabel(const QSqlDatabase& db, Label* label);
static bool deleteLabel(const QSqlDatabase& db, Label* label);

View File

@ -95,6 +95,24 @@ QIcon Label::generateIcon(const QColor& color) {
return pxm;
}
void Label::assignToMessage(const Message& msg) {
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
DatabaseQueries::assignLabelToMessage(database, this, msg);
updateCounts(true);
getParentServiceRoot()->itemChanged({ this });
}
void Label::deassignFromMessage(const Message& msg) {
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
DatabaseQueries::deassignLabelFromMessage(database, this, msg);
updateCounts(true);
getParentServiceRoot()->itemChanged({ this });
}
void Label::setCountOfAllMessages(int totalCount) {
m_totalCount = totalCount;
}

View File

@ -29,6 +29,10 @@ class Label : public RootItem {
virtual void updateCounts(bool including_total_count);
static QIcon generateIcon(const QColor& color);
public slots:
void assignToMessage(const Message& msg);
void deassignFromMessage(const Message& msg);
private:
QColor m_color;
int m_totalCount{};