mirror of
https://github.com/martinrotter/rssguard.git
synced 2024-12-27 08:33:27 +01:00
Ability to edit/delete tags.
This commit is contained in:
parent
205c32735f
commit
1e1b3f5255
@ -46,6 +46,7 @@
|
||||
<file>./graphics/Faenza/actions/64/system-search.png</file>
|
||||
<file>./graphics/Faenza/actions/64/system-upgrade.png</file>
|
||||
<file>./graphics/Faenza/actions/64/tab-new.png</file>
|
||||
<file>./graphics/Faenza/actions/64/tag-new.png</file>
|
||||
<file>./graphics/Faenza/actions/64/up.png</file>
|
||||
<file>./graphics/Faenza/actions/64/view-fullscreen.png</file>
|
||||
<file>./graphics/Faenza/actions/64/view-list-details.png</file>
|
||||
@ -114,6 +115,9 @@
|
||||
<file>./graphics/Numix/22/actions/system-search.svg</file>
|
||||
<file>./graphics/Numix/22/actions/system-upgrade.svg</file>
|
||||
<file>./graphics/Numix/22/actions/tab-new.svg</file>
|
||||
<file>./graphics/Numix/22/actions/tag-folder.svg</file>
|
||||
<file>./graphics/Numix/22/actions/tag-new.svg</file>
|
||||
<file>./graphics/Numix/22/actions/tag-properties.svg</file>
|
||||
<file>./graphics/Numix/22/actions/up.svg</file>
|
||||
<file>./graphics/Numix/22/actions/view-fullscreen.svg</file>
|
||||
<file>./graphics/Numix/22/actions/view-list-details.svg</file>
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "services/abstract/label.h"
|
||||
|
||||
FormAddEditLabel::FormAddEditLabel(QWidget* parent) : QDialog(parent) {
|
||||
FormAddEditLabel::FormAddEditLabel(QWidget* parent) : QDialog(parent), m_editableLabel(nullptr) {
|
||||
m_ui.setupUi(this);
|
||||
m_ui.m_txtName->lineEdit()->setPlaceholderText(tr("Name for your label"));
|
||||
|
||||
@ -26,11 +26,10 @@ FormAddEditLabel::FormAddEditLabel(QWidget* parent) : QDialog(parent) {
|
||||
}
|
||||
|
||||
Label* FormAddEditLabel::execForAdd() {
|
||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("tag-properties")), tr("Create new label"));
|
||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("tag-new")), 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());
|
||||
@ -39,3 +38,23 @@ Label* FormAddEditLabel::execForAdd() {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool FormAddEditLabel::execForEdit(Label* lbl) {
|
||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("tag-properties")), tr("Edit label '%1'").arg(lbl->title()));
|
||||
|
||||
m_editableLabel = lbl;
|
||||
m_ui.m_btnColor->setColor(lbl->color());
|
||||
m_ui.m_txtName->lineEdit()->setText(lbl->title());
|
||||
|
||||
auto exit_code = exec();
|
||||
|
||||
if (exit_code == QDialog::DialogCode::Accepted) {
|
||||
// TODO: Place server-side changes perhaps to here?
|
||||
m_editableLabel->setColor(m_ui.m_btnColor->color());
|
||||
m_editableLabel->setTitle(m_ui.m_txtName->lineEdit()->text());
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,11 @@ class FormAddEditLabel : public QDialog {
|
||||
|
||||
public slots:
|
||||
Label* execForAdd();
|
||||
bool execForEdit(Label* lbl);
|
||||
|
||||
private:
|
||||
Ui::FormAddEditLabel m_ui;
|
||||
Label* m_editableLabel;
|
||||
};
|
||||
|
||||
#endif // FORMADDEDITLABEL_H
|
||||
|
@ -29,7 +29,8 @@
|
||||
|
||||
FeedsView::FeedsView(QWidget* parent)
|
||||
: QTreeView(parent), m_contextMenuService(nullptr), m_contextMenuBin(nullptr), m_contextMenuCategories(nullptr),
|
||||
m_contextMenuFeeds(nullptr), m_contextMenuImportant(nullptr), m_contextMenuEmptySpace(nullptr), m_contextMenuOtherItems(nullptr) {
|
||||
m_contextMenuFeeds(nullptr), m_contextMenuImportant(nullptr), m_contextMenuEmptySpace(nullptr), m_contextMenuOtherItems(nullptr),
|
||||
m_contextMenuLabel(nullptr) {
|
||||
setObjectName(QSL("FeedsView"));
|
||||
|
||||
// Allocate models.
|
||||
@ -656,6 +657,28 @@ QMenu* FeedsView::initializeContextMenuOtherItem(RootItem* clicked_item) {
|
||||
return m_contextMenuOtherItems;
|
||||
}
|
||||
|
||||
QMenu* FeedsView::initializeContextMenuLabel(RootItem* clicked_item) {
|
||||
if (m_contextMenuLabel == nullptr) {
|
||||
m_contextMenuLabel = new QMenu(tr("Context menu for label"), this);
|
||||
}
|
||||
else {
|
||||
m_contextMenuLabel->clear();
|
||||
}
|
||||
|
||||
QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList();
|
||||
|
||||
if (!specific_actions.isEmpty()) {
|
||||
m_contextMenuLabel->addSeparator();
|
||||
m_contextMenuLabel->addActions(specific_actions);
|
||||
}
|
||||
else {
|
||||
m_contextMenuLabel->addAction(qApp->mainForm()->m_ui->m_actionEditSelectedItem);
|
||||
m_contextMenuLabel->addAction(qApp->mainForm()->m_ui->m_actionDeleteSelectedItem);
|
||||
}
|
||||
|
||||
return m_contextMenuLabel;
|
||||
}
|
||||
|
||||
void FeedsView::setupAppearance() {
|
||||
// Setup column resize strategies.
|
||||
header()->setSectionResizeMode(FDS_MODEL_TITLE_INDEX, QHeaderView::Stretch);
|
||||
@ -722,6 +745,9 @@ void FeedsView::contextMenuEvent(QContextMenuEvent* event) {
|
||||
else if (clicked_item->kind() == RootItem::Kind::ServiceRoot) {
|
||||
initializeContextMenuService(clicked_item)->exec(event->globalPos());
|
||||
}
|
||||
else if (clicked_item->kind() == RootItem::Kind::Label) {
|
||||
initializeContextMenuLabel(clicked_item)->exec(event->globalPos());
|
||||
}
|
||||
else {
|
||||
initializeContextMenuOtherItem(clicked_item)->exec(event->globalPos());
|
||||
}
|
||||
|
@ -110,6 +110,7 @@ class RSSGUARD_DLLSPEC FeedsView : public QTreeView {
|
||||
QMenu* initializeContextMenuImportant(RootItem* clicked_item);
|
||||
QMenu* initializeContextMenuEmptySpace();
|
||||
QMenu* initializeContextMenuOtherItem(RootItem* clicked_item);
|
||||
QMenu* initializeContextMenuLabel(RootItem* clicked_item);
|
||||
|
||||
void setupAppearance();
|
||||
void saveExpandStates(RootItem* item);
|
||||
@ -121,6 +122,7 @@ class RSSGUARD_DLLSPEC FeedsView : public QTreeView {
|
||||
QMenu* m_contextMenuImportant;
|
||||
QMenu* m_contextMenuEmptySpace;
|
||||
QMenu* m_contextMenuOtherItems;
|
||||
QMenu* m_contextMenuLabel;
|
||||
FeedsModel* m_sourceModel;
|
||||
FeedsProxyModel* m_proxyModel;
|
||||
};
|
||||
|
@ -54,6 +54,42 @@ QList<Label*> DatabaseQueries::getLabels(const QSqlDatabase& db, int account_id)
|
||||
return labels;
|
||||
}
|
||||
|
||||
bool DatabaseQueries::updateLabel(const QSqlDatabase& db, Label* label) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare("UPDATE Labels SET name = :name, color = :color "
|
||||
"WHERE id = :id AND account_id = :account_id;");
|
||||
q.bindValue(QSL(":name"), label->title());
|
||||
q.bindValue(QSL(":color"), label->color().name());
|
||||
q.bindValue(QSL(":id"), label->id());
|
||||
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
|
||||
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
bool DatabaseQueries::deleteLabel(const QSqlDatabase& db, Label* label) {
|
||||
// NOTE: All dependecies are done via SQL foreign cascaded keys, so no
|
||||
// extra removals are needed.
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare("DELETE FROM Labels WHERE id = :id AND account_id = :account_id;");
|
||||
q.bindValue(QSL(":id"), label->id());
|
||||
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
|
||||
|
||||
if (q.exec()) {
|
||||
q.prepare("DELETE FROM LabelsInMessages WHERE label = :custom_id AND account_id = :account_id;");
|
||||
q.bindValue(QSL(":custom_id"), label->customId());
|
||||
q.bindValue(QSL(":account_id"), label->getParentServiceRoot()->accountId());
|
||||
|
||||
return q.exec();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int account_id) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
@ -70,7 +106,10 @@ bool DatabaseQueries::createLabel(const QSqlDatabase& db, Label* label, int acco
|
||||
label->setId(q.lastInsertId().toInt());
|
||||
}
|
||||
|
||||
return res;
|
||||
// Fixup missing custom IDs.
|
||||
q.prepare("UPDATE Labels SET custom_id = id WHERE custom_id IS NULL OR custom_id = '';");
|
||||
|
||||
return q.exec() && res;
|
||||
}
|
||||
|
||||
bool DatabaseQueries::markImportantMessagesReadUnread(const QSqlDatabase& db, int account_id, RootItem::ReadStatus read) {
|
||||
|
@ -20,6 +20,8 @@ class DatabaseQueries {
|
||||
|
||||
// Label operators.
|
||||
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);
|
||||
static bool createLabel(const QSqlDatabase& db, Label* label, int account_id);
|
||||
|
||||
// Message operators.
|
||||
|
@ -2,6 +2,12 @@
|
||||
|
||||
#include "services/abstract/label.h"
|
||||
|
||||
#include "gui/dialogs/formaddeditlabel.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/databasefactory.h"
|
||||
#include "miscellaneous/databasequeries.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
@ -23,6 +29,39 @@ void Label::setColor(const QColor& color) {
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
bool Label::canBeEdited() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Label::editViaGui() {
|
||||
FormAddEditLabel form(qApp->mainFormWidget());
|
||||
|
||||
if (form.execForEdit(this)) {
|
||||
QSqlDatabase db = qApp->database()->connection(metaObject()->className());
|
||||
|
||||
return DatabaseQueries::updateLabel(db, this);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Label::canBeDeleted() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Label::deleteViaGui() {
|
||||
QSqlDatabase db = qApp->database()->connection(metaObject()->className());
|
||||
|
||||
if (DatabaseQueries::deleteLabel(db, this)) {
|
||||
getParentServiceRoot()->requestItemRemoval(this);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QIcon Label::generateIcon(const QColor& color) {
|
||||
QPixmap pxm(64, 64);
|
||||
|
||||
|
@ -17,6 +17,10 @@ class Label : public RootItem {
|
||||
QColor color() const;
|
||||
void setColor(const QColor& color);
|
||||
|
||||
virtual bool canBeEdited() const;
|
||||
virtual bool editViaGui();
|
||||
virtual bool canBeDeleted() const;
|
||||
virtual bool deleteViaGui();
|
||||
static QIcon generateIcon(const QColor& color);
|
||||
|
||||
private:
|
||||
|
@ -12,7 +12,7 @@
|
||||
LabelsNode::LabelsNode(const QList<Label*>& labels, RootItem* parent_item) : RootItem(parent_item), m_actLabelNew(nullptr) {
|
||||
setKind(RootItem::Kind::Labels);
|
||||
setId(ID_LABELS);
|
||||
setIcon(qApp->icons()->fromTheme(QSL("mail-mark-important")));
|
||||
setIcon(qApp->icons()->fromTheme(QSL("tag-folder")));
|
||||
setTitle(tr("Labels"));
|
||||
setDescription(tr("You can see all your labels (tags) here."));
|
||||
setCreationDate(QDateTime::currentDateTime());
|
||||
@ -25,7 +25,7 @@ LabelsNode::LabelsNode(const QList<Label*>& labels, RootItem* parent_item) : Roo
|
||||
QList<QAction*> LabelsNode::contextMenuFeedsList() {
|
||||
if (m_actLabelNew == nullptr) {
|
||||
// Initialize it all.
|
||||
m_actLabelNew = new QAction(qApp->icons()->fromTheme("tag-new"), tr("New label"), this);
|
||||
m_actLabelNew = new QAction(qApp->icons()->fromTheme(QSL("tag-new")), tr("New label"), this);
|
||||
|
||||
connect(m_actLabelNew, &QAction::triggered, this, &LabelsNode::createLabel);
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ bool ServiceRoot::loadMessagesForItem(RootItem* item, MessagesModel* model) {
|
||||
// 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())));
|
||||
.arg(QString::number(accountId()), item->customId()));
|
||||
}
|
||||
else if (item->kind() == RootItem::Kind::Labels) {
|
||||
// Show messages with any label.
|
||||
|
Loading…
Reference in New Issue
Block a user