Work on labels.

This commit is contained in:
Martin Rotter 2020-10-07 16:10:57 +02:00
parent 580457ae12
commit 26e4431d3b
12 changed files with 165 additions and 57 deletions

View File

@ -5,6 +5,7 @@
#include <QColorDialog> #include <QColorDialog>
#include <QPainter> #include <QPainter>
#include <QPainterPath> #include <QPainterPath>
#include <QRandomGenerator>
ColorToolButton::ColorToolButton(QWidget* parent) : QToolButton(parent), m_color(Qt::GlobalColor::black) { ColorToolButton::ColorToolButton(QWidget* parent) : QToolButton(parent), m_color(Qt::GlobalColor::black) {
connect(this, &ColorToolButton::clicked, this, [this]() { connect(this, &ColorToolButton::clicked, this, [this]() {
@ -29,6 +30,14 @@ void ColorToolButton::setColor(const QColor& color) {
repaint(); repaint();
} }
void ColorToolButton::setRandomColor() {
auto rnd_color = QRandomGenerator::global()->bounded(0xFFFFFF);
auto rnd_color_name = QString("#%1").arg(QString::number(rnd_color, 16));
setColor(rnd_color_name);
emit colorChanged(rnd_color_name);
}
void ColorToolButton::paintEvent(QPaintEvent* e) { void ColorToolButton::paintEvent(QPaintEvent* e) {
Q_UNUSED(e) Q_UNUSED(e)
QPainter p(this); QPainter p(this);
@ -46,6 +55,5 @@ void ColorToolButton::paintEvent(QPaintEvent* e) {
QPainterPath path; QPainterPath path;
path.addRoundedRect(QRectF(rect), 3, 3); path.addRoundedRect(QRectF(rect), 3, 3);
p.fillPath(path, m_color); p.fillPath(path, m_color);
} }

View File

@ -14,6 +14,9 @@ class ColorToolButton : public QToolButton {
QColor color() const; QColor color() const;
void setColor(const QColor& color); void setColor(const QColor& color);
public slots:
void setRandomColor();
signals: signals:
void colorChanged(const QColor& new_color); void colorChanged(const QColor& new_color);

View File

@ -2,18 +2,40 @@
#include "gui/dialogs/formaddeditlabel.h" #include "gui/dialogs/formaddeditlabel.h"
#include "gui/guiutilities.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "services/abstract/label.h" #include "services/abstract/label.h"
FormAddEditLabel::FormAddEditLabel(QWidget* parent) : QDialog(parent), ui(new Ui::FormAddEditLabel) { FormAddEditLabel::FormAddEditLabel(QWidget* parent) : QDialog(parent) {
ui->setupUi(this); m_ui.setupUi(this);
} m_ui.m_txtName->lineEdit()->setPlaceholderText(tr("Name for your label"));
FormAddEditLabel::~FormAddEditLabel() { connect(m_ui.m_txtName->lineEdit(), &QLineEdit::textChanged, this, [this](const QString& text) {
delete ui; m_ui.m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(!text.isEmpty());
if (text.isEmpty()) {
m_ui.m_txtName->setStatus(LineEditWithStatus::StatusType::Error, tr("Label's name cannot be empty."));
}
else {
m_ui.m_txtName->setStatus(LineEditWithStatus::StatusType::Ok, tr("Perfect!"));
}
});
m_ui.m_txtName->lineEdit()->setText(tr("Hot stuff"));
} }
Label* FormAddEditLabel::execForAdd() { Label* FormAddEditLabel::execForAdd() {
auto exit_code = exec(); GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("tag-properties")), tr("Create new label"));
m_ui.m_btnColor->setRandomColor();
auto exit_code = exec();
auto xxx = m_ui.m_btnColor->color().name();
if (exit_code == QDialog::DialogCode::Accepted) {
return new Label(m_ui.m_txtName->lineEdit()->text(), m_ui.m_btnColor->color());
}
else {
return nullptr; return nullptr;
} }
}

View File

@ -18,13 +18,12 @@ class FormAddEditLabel : public QDialog {
public: public:
explicit FormAddEditLabel(QWidget* parent = nullptr); explicit FormAddEditLabel(QWidget* parent = nullptr);
~FormAddEditLabel();
public slots: public slots:
Label* execForAdd(); Label* execForAdd();
private: private:
Ui::FormAddEditLabel* ui; Ui::FormAddEditLabel m_ui;
}; };
#endif // FORMADDEDITLABEL_H #endif // FORMADDEDITLABEL_H

View File

@ -6,35 +6,29 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>224</width>
<height>300</height> <height>97</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Dialog</string>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item row="0" column="0"> <item>
<widget class="QLabel" name="label"> <layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="ColorToolButton" name="m_btnColor">
<property name="text"> <property name="text">
<string>Name</string> <string>...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item>
<widget class="LineEditWithStatus" name="widget" native="true"/> <widget class="LineEditWithStatus" name="m_txtName" native="true"/>
</item> </item>
<item row="3" column="0" colspan="2"> </layout>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item> </item>
<item row="2" column="0" colspan="2"> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -47,17 +41,13 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="1" column="0"> <item>
<widget class="QLabel" name="label_2"> <widget class="QDialogButtonBox" name="m_buttonBox">
<property name="text"> <property name="orientation">
<string>Color</string> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> <property name="standardButtons">
</item> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<item row="1" column="1">
<widget class="ColorToolButton" name="toolButton">
<property name="text">
<string>...</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -76,37 +66,40 @@
<header>colortoolbutton.h</header> <header>colortoolbutton.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<tabstops>
<tabstop>m_btnColor</tabstop>
</tabstops>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>
<sender>buttonBox</sender> <sender>m_buttonBox</sender>
<signal>accepted()</signal> <signal>accepted()</signal>
<receiver>FormAddEditLabel</receiver> <receiver>FormAddEditLabel</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>248</x> <x>214</x>
<y>254</y> <y>132</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
<y>274</y> <y>141</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection> <connection>
<sender>buttonBox</sender> <sender>m_buttonBox</sender>
<signal>rejected()</signal> <signal>rejected()</signal>
<receiver>FormAddEditLabel</receiver> <receiver>FormAddEditLabel</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>316</x> <x>214</x>
<y>260</y> <y>132</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>223</x>
<y>274</y> <y>141</y>
</hint> </hint>
</hints> </hints>
</connection> </connection>

View File

@ -31,6 +31,25 @@
#include <QUrl> #include <QUrl>
#include <QVariant> #include <QVariant>
bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int account_id) {
QSqlQuery q(db);
q.setForwardOnly(true);
q.prepare("INSERT INTO Labels (name, color, custom_id, account_id) "
"VALUES (:name, :color, :custom_id, :account_id);");
q.bindValue(QSL(":name"), label->title());
q.bindValue(QSL(":color"), label->color().name());
q.bindValue(QSL(":custom_id"), label->customId());
q.bindValue(QSL(":account_id"), account_id);
auto res = q.exec();
if (res && q.lastInsertId().isValid()) {
label->setId(q.lastInsertId().toInt());
}
return res;
}
bool DatabaseQueries::markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read) { bool DatabaseQueries::markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read) {
QSqlQuery q(db); QSqlQuery q(db);

View File

@ -7,6 +7,7 @@
#include "core/messagefilter.h" #include "core/messagefilter.h"
#include "services/abstract/category.h" #include "services/abstract/category.h"
#include "services/abstract/label.h"
#include "services/abstract/serviceroot.h" #include "services/abstract/serviceroot.h"
#include "services/standard/standardfeed.h" #include "services/standard/standardfeed.h"
@ -17,6 +18,9 @@
class DatabaseQueries { class DatabaseQueries {
public: public:
// Label operators.
static bool createLabel(const QSqlDatabase& db, Label* label, int account_id);
// Message operators. // Message operators.
static bool markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read); static bool markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read);
static bool markMessagesReadUnread(const QSqlDatabase& db, const QStringList& ids, RootItem::ReadStatus read); static bool markMessagesReadUnread(const QSqlDatabase& db, const QStringList& ids, RootItem::ReadStatus read);

View File

@ -2,6 +2,37 @@
#include "services/abstract/label.h" #include "services/abstract/label.h"
Label::Label(RootItem* parent_item) : RootItem(parent_item), m_name(QString()), m_backColor(QColor()) { #include <QPainter>
setKind(RootItem::Kind::Labels); #include <QPainterPath>
Label::Label(const QString& name, const QColor& color, RootItem* parent_item) : RootItem(parent_item) {
setColor(color);
setTitle(name);
}
Label::Label(RootItem* parent_item) : RootItem(parent_item) {
setKind(RootItem::Kind::Label);
}
QColor Label::color() const {
return m_color;
}
void Label::setColor(const QColor& color) {
setIcon(generateIcon(color));
m_color = color;
}
QIcon Label::generateIcon(const QColor& color) {
QPixmap pxm(64, 64);
pxm.fill(Qt::GlobalColor::transparent);
QPainter paint(&pxm);
QPainterPath path;
path.addRoundedRect(QRectF(pxm.rect()), 10, 10);
paint.fillPath(path, color);
return pxm;
} }

View File

@ -11,11 +11,16 @@ class Label : public RootItem {
Q_OBJECT Q_OBJECT
public: public:
explicit Label(const QString& name, const QColor& color, RootItem* parent_item = nullptr);
explicit Label(RootItem* parent_item = nullptr); explicit Label(RootItem* parent_item = nullptr);
QColor color() const;
void setColor(const QColor& color);
static QIcon generateIcon(const QColor& color);
private: private:
QString m_name; QColor m_color;
QColor m_backColor;
}; };
#endif // LABEL_H #endif // LABEL_H

View File

@ -4,6 +4,8 @@
#include "gui/dialogs/formaddeditlabel.h" #include "gui/dialogs/formaddeditlabel.h"
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/databasefactory.h"
#include "miscellaneous/databasequeries.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "services/abstract/serviceroot.h" #include "services/abstract/serviceroot.h"
@ -31,6 +33,13 @@ QList<QAction*> LabelsNode::contextMenuFeedsList() {
void LabelsNode::createLabel() { void LabelsNode::createLabel() {
FormAddEditLabel frm(qApp->mainFormWidget()); FormAddEditLabel frm(qApp->mainFormWidget());
Label* new_lbl = frm.execForAdd();
frm.execForAdd(); if (new_lbl != nullptr) {
QSqlDatabase db = qApp->database()->connection(metaObject()->className());
DatabaseQueries::createLabel(db, new_lbl, getParentServiceRoot()->accountId());
getParentServiceRoot()->requestItemReassignment(new_lbl, this);
}
} }

View File

@ -502,6 +502,18 @@ bool ServiceRoot::loadMessagesForItem(RootItem* item, MessagesModel* model) {
model->setFilter(QString("Messages.is_important = 1 AND Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = %1") model->setFilter(QString("Messages.is_important = 1 AND Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = %1")
.arg(QString::number(accountId()))); .arg(QString::number(accountId())));
} }
else if (item->kind() == RootItem::Kind::Label) {
// Show messages with particular label.
model->setFilter(QString("Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = %1 AND "
"(SELECT COUNT(*) FROM LabelsInMessages WHERE account_id = %1 AND message = Messages.custom_id AND label = %2) > 0")
.arg(QString::number(accountId()), QString::number(item->id())));
}
else if (item->kind() == RootItem::Kind::Labels) {
// Show messages with any label.
model->setFilter(QString("Messages.is_deleted = 0 AND Messages.is_pdeleted = 0 AND Messages.account_id = %1 AND "
"(SELECT COUNT(*) FROM LabelsInMessages WHERE account_id = %1 AND message = Messages.custom_id) > 0")
.arg(QString::number(accountId())));
}
else { else {
QList<Feed*> children = item->getSubTreeFeeds(); QList<Feed*> children = item->getSubTreeFeeds();
QString filter_clause = textualFeedIds(children).join(QSL(", ")); QString filter_clause = textualFeedIds(children).join(QSL(", "));

View File

@ -143,6 +143,9 @@ void StandardServiceRoot::loadFromDatabase() {
appendChild(recycleBin()); appendChild(recycleBin());
appendChild(importantNode()); appendChild(importantNode());
appendChild(new LabelsNode(this)); appendChild(new LabelsNode(this));
// TODO: Load all labels and append.
updateCounts(true); updateCounts(true);
} }