mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-01-30 00:55:16 +01:00
Save work on DB layer and DB models.
This commit is contained in:
parent
8e2eede3ed
commit
f29ea98bbb
@ -54,7 +54,7 @@ CREATE TABLE Messages (
|
||||
is_important INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_important >= 0 AND is_important <= 1),
|
||||
is_deleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_deleted >= 0 AND is_deleted <= 1),
|
||||
is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1),
|
||||
feed_custom_id TEXT NOT NULL, /* Points to Feeds/custom_id. */
|
||||
feed TEXT NOT NULL, /* Points to Feeds/custom_id. */
|
||||
title TEXT NOT NULL CHECK (title != ''),
|
||||
url TEXT,
|
||||
author TEXT,
|
||||
|
@ -177,11 +177,13 @@ void MessagesModel::setupHeaderData() {
|
||||
|
||||
/*: Tooltip for "read" column in msg list.*/ tr("Read") <<
|
||||
|
||||
/*: Tooltip for "deleted" column in msg list.*/ tr("Deleted") <<
|
||||
|
||||
/*: Tooltip for "important" column in msg list.*/ tr("Important") <<
|
||||
|
||||
/*: Tooltip for name of feed for message.*/ tr("Feed") <<
|
||||
/*: Tooltip for "deleted" column in msg list.*/ tr("Deleted") <<
|
||||
|
||||
/*: Tooltip for "pdeleted" column in msg list.*/ tr("Permanently deleted") <<
|
||||
|
||||
/*: Tooltip for custom ID of feed of message.*/ tr("Feed ID") <<
|
||||
|
||||
/*: Tooltip for title of message.*/ tr("Title") <<
|
||||
|
||||
@ -193,8 +195,6 @@ void MessagesModel::setupHeaderData() {
|
||||
|
||||
/*: Tooltip for contents of message.*/ tr("Contents") <<
|
||||
|
||||
/*: Tooltip for "pdeleted" column in msg list.*/ tr("Permanently deleted") <<
|
||||
|
||||
/*: Tooltip for attachments of message.*/ tr("Attachments") <<
|
||||
|
||||
/*: Tooltip for account ID of message.*/ tr("Account ID") <<
|
||||
@ -203,7 +203,7 @@ void MessagesModel::setupHeaderData() {
|
||||
|
||||
/*: Tooltip for custom hash string of message.*/ tr("Custom hash") <<
|
||||
|
||||
/*: Tooltip for custom ID of feed of message.*/ tr("Feed ID") <<
|
||||
/*: Tooltip for name of feed for message.*/ tr("Feed") <<
|
||||
|
||||
/*: Tooltip for indication of presence of enclosures.*/ tr("Has enclosures");
|
||||
|
||||
|
@ -13,39 +13,39 @@ MessagesModelSqlLayer::MessagesModelSqlLayer()
|
||||
// Used in <x>: SELECT <x1>, <x2> FROM ....;
|
||||
m_fieldNames[MSG_DB_ID_INDEX] = "Messages.id";
|
||||
m_fieldNames[MSG_DB_READ_INDEX] = "Messages.is_read";
|
||||
m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
|
||||
m_fieldNames[MSG_DB_IMPORTANT_INDEX] = "Messages.is_important";
|
||||
m_fieldNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
|
||||
m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
|
||||
m_fieldNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
|
||||
m_fieldNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
|
||||
m_fieldNames[MSG_DB_TITLE_INDEX] = "Messages.title";
|
||||
m_fieldNames[MSG_DB_URL_INDEX] = "Messages.url";
|
||||
m_fieldNames[MSG_DB_AUTHOR_INDEX] = "Messages.author";
|
||||
m_fieldNames[MSG_DB_DCREATED_INDEX] = "Messages.date_created";
|
||||
m_fieldNames[MSG_DB_CONTENTS_INDEX] = "Messages.contents";
|
||||
m_fieldNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
|
||||
m_fieldNames[MSG_DB_ENCLOSURES_INDEX] = "Messages.enclosures";
|
||||
m_fieldNames[MSG_DB_ACCOUNT_ID_INDEX] = "Messages.account_id";
|
||||
m_fieldNames[MSG_DB_CUSTOM_ID_INDEX] = "Messages.custom_id";
|
||||
m_fieldNames[MSG_DB_CUSTOM_HASH_INDEX] = "Messages.custom_hash";
|
||||
m_fieldNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
|
||||
m_fieldNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
|
||||
m_fieldNames[MSG_DB_HAS_ENCLOSURES] = "CASE WHEN length(Messages.enclosures) > 10 THEN 'true' ELSE 'false' END AS has_enclosures";
|
||||
|
||||
// Used in <x>: SELECT ... FROM ... ORDER BY <x1> DESC, <x2> ASC;
|
||||
m_orderByNames[MSG_DB_ID_INDEX] = "Messages.id";
|
||||
m_orderByNames[MSG_DB_READ_INDEX] = "Messages.is_read";
|
||||
m_orderByNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
|
||||
m_orderByNames[MSG_DB_IMPORTANT_INDEX] = "Messages.is_important";
|
||||
m_orderByNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
|
||||
m_orderByNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
|
||||
m_orderByNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
|
||||
m_orderByNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
|
||||
m_orderByNames[MSG_DB_TITLE_INDEX] = "Messages.title";
|
||||
m_orderByNames[MSG_DB_URL_INDEX] = "Messages.url";
|
||||
m_orderByNames[MSG_DB_AUTHOR_INDEX] = "Messages.author";
|
||||
m_orderByNames[MSG_DB_DCREATED_INDEX] = "Messages.date_created";
|
||||
m_orderByNames[MSG_DB_CONTENTS_INDEX] = "Messages.contents";
|
||||
m_orderByNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
|
||||
m_orderByNames[MSG_DB_ENCLOSURES_INDEX] = "Messages.enclosures";
|
||||
m_orderByNames[MSG_DB_ACCOUNT_ID_INDEX] = "Messages.account_id";
|
||||
m_orderByNames[MSG_DB_CUSTOM_ID_INDEX] = "Messages.custom_id";
|
||||
m_orderByNames[MSG_DB_CUSTOM_HASH_INDEX] = "Messages.custom_hash";
|
||||
m_orderByNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
|
||||
m_orderByNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
|
||||
m_orderByNames[MSG_DB_HAS_ENCLOSURES] = "has_enclosures";
|
||||
|
||||
m_numericColumns << MSG_DB_ID_INDEX << MSG_DB_READ_INDEX << MSG_DB_DELETED_INDEX << MSG_DB_PDELETED_INDEX
|
||||
|
@ -176,20 +176,20 @@
|
||||
// Indexes of columns as they are DEFINED IN THE TABLE for MESSAGES.
|
||||
#define MSG_DB_ID_INDEX 0
|
||||
#define MSG_DB_READ_INDEX 1
|
||||
#define MSG_DB_DELETED_INDEX 2
|
||||
#define MSG_DB_IMPORTANT_INDEX 3
|
||||
#define MSG_DB_FEED_TITLE_INDEX 4
|
||||
#define MSG_DB_TITLE_INDEX 5
|
||||
#define MSG_DB_URL_INDEX 6
|
||||
#define MSG_DB_AUTHOR_INDEX 7
|
||||
#define MSG_DB_DCREATED_INDEX 8
|
||||
#define MSG_DB_CONTENTS_INDEX 9
|
||||
#define MSG_DB_PDELETED_INDEX 10
|
||||
#define MSG_DB_IMPORTANT_INDEX 2
|
||||
#define MSG_DB_DELETED_INDEX 3
|
||||
#define MSG_DB_PDELETED_INDEX 4
|
||||
#define MSG_DB_FEED_CUSTOM_ID_INDEX 5
|
||||
#define MSG_DB_TITLE_INDEX 6
|
||||
#define MSG_DB_URL_INDEX 7
|
||||
#define MSG_DB_AUTHOR_INDEX 8
|
||||
#define MSG_DB_DCREATED_INDEX 9
|
||||
#define MSG_DB_CONTENTS_INDEX 10
|
||||
#define MSG_DB_ENCLOSURES_INDEX 11
|
||||
#define MSG_DB_ACCOUNT_ID_INDEX 12
|
||||
#define MSG_DB_CUSTOM_ID_INDEX 13
|
||||
#define MSG_DB_CUSTOM_HASH_INDEX 14
|
||||
#define MSG_DB_FEED_CUSTOM_ID_INDEX 15
|
||||
#define MSG_DB_FEED_TITLE_INDEX 15
|
||||
#define MSG_DB_HAS_ENCLOSURES 16
|
||||
|
||||
// Indexes of columns as they are DEFINED IN THE TABLE for CATEGORIES.
|
||||
@ -209,18 +209,12 @@
|
||||
#define FDS_DB_DCREATED_INDEX 3
|
||||
#define FDS_DB_ICON_INDEX 4
|
||||
#define FDS_DB_CATEGORY_INDEX 5
|
||||
#define FDS_DB_ENCODING_INDEX 6
|
||||
#define FDS_DB_SOURCE_TYPE_INDEX 7
|
||||
#define FDS_DB_URL_INDEX 8
|
||||
#define FDS_DB_POST_PROCESS 9
|
||||
#define FDS_DB_PROTECTED_INDEX 10
|
||||
#define FDS_DB_USERNAME_INDEX 11
|
||||
#define FDS_DB_PASSWORD_INDEX 12
|
||||
#define FDS_DB_UPDATE_TYPE_INDEX 13
|
||||
#define FDS_DB_UPDATE_INTERVAL_INDEX 14
|
||||
#define FDS_DB_TYPE_INDEX 15
|
||||
#define FDS_DB_ACCOUNT_ID_INDEX 16
|
||||
#define FDS_DB_CUSTOM_ID_INDEX 17
|
||||
#define FDS_DB_SOURCE_INDEX 6
|
||||
#define FDS_DB_UPDATE_TYPE_INDEX 7
|
||||
#define FDS_DB_UPDATE_INTERVAL_INDEX 8
|
||||
#define FDS_DB_ACCOUNT_ID_INDEX 9
|
||||
#define FDS_DB_CUSTOM_ID_INDEX 10
|
||||
#define FDS_DB_CUSTOM_DATA_INDEX 11
|
||||
|
||||
// Indexes of columns for feed models.
|
||||
#define FDS_MODEL_TITLE_INDEX 0
|
||||
|
@ -19,7 +19,7 @@ FormBackupDatabaseSettings::FormBackupDatabaseSettings(QWidget* parent) : QDialo
|
||||
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
|
||||
connect(m_ui->m_checkBackupDatabase, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
|
||||
connect(m_ui->m_checkBackupSettings, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
|
||||
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormBackupDatabaseSettings::performBackup);
|
||||
connect(m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok), &QPushButton::clicked, this, &FormBackupDatabaseSettings::performBackup);
|
||||
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkBackupNames);
|
||||
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkOkButton);
|
||||
connect(m_ui->m_btnSelectFolder, &QPushButton::clicked, this, &FormBackupDatabaseSettings::selectFolderInitial);
|
||||
@ -76,7 +76,7 @@ void FormBackupDatabaseSettings::checkBackupNames(const QString& name) {
|
||||
}
|
||||
|
||||
void FormBackupDatabaseSettings::checkOkButton() {
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setDisabled(m_ui->m_txtBackupName->lineEdit()->text().simplified().isEmpty() ||
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setDisabled(m_ui->m_txtBackupName->lineEdit()->text().simplified().isEmpty() ||
|
||||
m_ui->m_lblSelectFolder->label()->text().simplified().isEmpty() ||
|
||||
(!m_ui->m_checkBackupDatabase->isChecked() &&
|
||||
!m_ui->m_checkBackupSettings->isChecked()));
|
||||
|
@ -17,7 +17,7 @@ FormDatabaseCleanup::FormDatabaseCleanup(QWidget* parent) : QDialog(parent), m_u
|
||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("edit-clear")));
|
||||
|
||||
connect(m_ui->m_spinDays, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &FormDatabaseCleanup::updateDaysSuffix);
|
||||
connect(m_ui->m_btnBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormDatabaseCleanup::startPurging);
|
||||
connect(m_ui->m_btnBox->button(QDialogButtonBox::StandardButton::Ok), &QPushButton::clicked, this, &FormDatabaseCleanup::startPurging);
|
||||
connect(this, &FormDatabaseCleanup::purgeRequested, &m_cleaner, &DatabaseCleaner::purgeDatabaseData);
|
||||
connect(&m_cleaner, &DatabaseCleaner::purgeStarted, this, &FormDatabaseCleanup::onPurgeStarted);
|
||||
connect(&m_cleaner, &DatabaseCleaner::purgeProgress, this, &FormDatabaseCleanup::onPurgeProgress);
|
||||
|
@ -25,7 +25,7 @@ FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget& parent) : QDia
|
||||
});
|
||||
connect(m_ui.m_groupDatabase, &QGroupBox::toggled, this, &FormRestoreDatabaseSettings::checkOkButton);
|
||||
connect(m_ui.m_groupSettings, &QGroupBox::toggled, this, &FormRestoreDatabaseSettings::checkOkButton);
|
||||
connect(m_ui.m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked,
|
||||
connect(m_ui.m_buttonBox->button(QDialogButtonBox::StandardButton::Ok), &QPushButton::clicked,
|
||||
this, &FormRestoreDatabaseSettings::performRestoration);
|
||||
selectFolder(qApp->documentsFolder());
|
||||
}
|
||||
@ -35,7 +35,7 @@ FormRestoreDatabaseSettings::~FormRestoreDatabaseSettings() {
|
||||
}
|
||||
|
||||
void FormRestoreDatabaseSettings::performRestoration() {
|
||||
m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
m_ui.m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(false);
|
||||
|
||||
try {
|
||||
qApp->restoreDatabaseSettings(m_ui.m_groupDatabase->isChecked(),
|
||||
@ -56,7 +56,7 @@ void FormRestoreDatabaseSettings::performRestoration() {
|
||||
|
||||
void FormRestoreDatabaseSettings::checkOkButton() {
|
||||
m_btnRestart->setEnabled(false);
|
||||
m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui.m_lblSelectFolder->label()->text().isEmpty() &&
|
||||
m_ui.m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(!m_ui.m_lblSelectFolder->label()->text().isEmpty() &&
|
||||
((m_ui.m_groupDatabase->isChecked() &&
|
||||
m_ui.m_listDatabase->currentRow() >= 0) ||
|
||||
(m_ui.m_groupSettings->isChecked() &&
|
||||
|
@ -13,9 +13,9 @@
|
||||
#include "miscellaneous/mutex.h"
|
||||
#include "miscellaneous/systemfactory.h"
|
||||
#include "services/abstract/feed.h"
|
||||
#include "services/abstract/gui/formcategorydetails.h"
|
||||
#include "services/abstract/rootitem.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
#include "services/standard/gui/formstandardcategorydetails.h"
|
||||
#include "services/standard/standardcategory.h"
|
||||
#include "services/standard/standardfeed.h"
|
||||
|
||||
|
@ -633,6 +633,8 @@ void MessagesView::adjustColumns() {
|
||||
hideColumn(MSG_DB_CUSTOM_ID_INDEX);
|
||||
hideColumn(MSG_DB_CUSTOM_HASH_INDEX);
|
||||
hideColumn(MSG_DB_FEED_CUSTOM_ID_INDEX);
|
||||
hideColumn(MSG_DB_FEED_TITLE_INDEX);
|
||||
hideColumn(MSG_DB_HAS_ENCLOSURES);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,7 @@ HEADERS += core/feeddownloader.h \
|
||||
services/abstract/feed.h \
|
||||
services/abstract/gui/authenticationdetails.h \
|
||||
services/abstract/gui/formaccountdetails.h \
|
||||
services/abstract/gui/formcategorydetails.h \
|
||||
services/abstract/gui/formfeeddetails.h \
|
||||
services/abstract/importantnode.h \
|
||||
services/abstract/label.h \
|
||||
@ -193,7 +194,6 @@ HEADERS += core/feeddownloader.h \
|
||||
services/standard/definitions.h \
|
||||
services/standard/feedparser.h \
|
||||
services/standard/gui/formeditstandardaccount.h \
|
||||
services/standard/gui/formstandardcategorydetails.h \
|
||||
services/standard/gui/formstandardfeeddetails.h \
|
||||
services/standard/gui/formstandardimportexport.h \
|
||||
services/standard/gui/standardfeeddetails.h \
|
||||
@ -322,6 +322,7 @@ SOURCES += core/feeddownloader.cpp \
|
||||
services/abstract/feed.cpp \
|
||||
services/abstract/gui/authenticationdetails.cpp \
|
||||
services/abstract/gui/formaccountdetails.cpp \
|
||||
services/abstract/gui/formcategorydetails.cpp \
|
||||
services/abstract/gui/formfeeddetails.cpp \
|
||||
services/abstract/importantnode.cpp \
|
||||
services/abstract/label.cpp \
|
||||
@ -365,7 +366,6 @@ SOURCES += core/feeddownloader.cpp \
|
||||
services/standard/atomparser.cpp \
|
||||
services/standard/feedparser.cpp \
|
||||
services/standard/gui/formeditstandardaccount.cpp \
|
||||
services/standard/gui/formstandardcategorydetails.cpp \
|
||||
services/standard/gui/formstandardfeeddetails.cpp \
|
||||
services/standard/gui/formstandardimportexport.cpp \
|
||||
services/standard/gui/standardfeeddetails.cpp \
|
||||
@ -416,6 +416,7 @@ FORMS += gui/dialogs/formabout.ui \
|
||||
network-web/downloadmanager.ui \
|
||||
services/abstract/gui/authenticationdetails.ui \
|
||||
services/abstract/gui/formaccountdetails.ui \
|
||||
services/abstract/gui/formcategorydetails.ui \
|
||||
services/abstract/gui/formfeeddetails.ui \
|
||||
services/feedly/gui/feedlyaccountdetails.ui \
|
||||
services/gmail/gui/formaddeditemail.ui \
|
||||
@ -424,7 +425,6 @@ FORMS += gui/dialogs/formabout.ui \
|
||||
services/greader/gui/greaderaccountdetails.ui \
|
||||
services/inoreader/gui/inoreaderaccountdetails.ui \
|
||||
services/owncloud/gui/owncloudaccountdetails.ui \
|
||||
services/standard/gui/formstandardcategorydetails.ui \
|
||||
services/standard/gui/formstandardimportexport.ui \
|
||||
services/standard/gui/standardfeeddetails.ui \
|
||||
services/tt-rss/gui/ttrssaccountdetails.ui \
|
||||
|
@ -1668,6 +1668,41 @@ QStringList DatabaseQueries::customIdsOfMessagesFromFeed(const QSqlDatabase& db,
|
||||
return ids;
|
||||
}
|
||||
|
||||
void DatabaseQueries::createOverwriteCategory(const QSqlDatabase& db, Category* category, int account_id, int parent_id) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
if (category->id() <= 0) {
|
||||
// We need to insert category first.
|
||||
q.prepare(QSL("INSERT INTO "
|
||||
"Categories (parent_id, title, date_created, account_id) "
|
||||
"VALUES (0, 'new', 0, %1);").arg(QString::number(account_id)));
|
||||
|
||||
if (!q.exec()) {
|
||||
throw ApplicationException(q.lastError().text());
|
||||
}
|
||||
else {
|
||||
category->setId(q.lastInsertId().toInt());
|
||||
}
|
||||
}
|
||||
|
||||
q.prepare("UPDATE Categories "
|
||||
"SET parent_id = :parent_id, title = :title, description = :description, date_created = :date_created, "
|
||||
" icon = :icon, account_id = :account_id, custom_id = :custom_id "
|
||||
"WHERE id = :id;");
|
||||
q.bindValue(QSL(":parent_id"), parent_id);
|
||||
q.bindValue(QSL(":title"), category->title());
|
||||
q.bindValue(QSL(":description"), category->description());
|
||||
q.bindValue(QSL(":date_created"), category->creationDate().toMSecsSinceEpoch());
|
||||
q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(category->icon()));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
q.bindValue(QSL(":custom_id"), category->customId());
|
||||
q.bindValue(QSL(":id"), category->id());
|
||||
|
||||
if (!q.exec()) {
|
||||
throw ApplicationException(q.lastError().text());
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, int account_id, int parent_id) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
@ -1675,7 +1710,7 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
|
||||
// We need to insert feed first.
|
||||
q.prepare(QSL("INSERT INTO "
|
||||
"Feeds (title, date_created, category, update_type, update_interval, account_id, custom_id) "
|
||||
"VALUES ('new', 0, 0, 0, 1, 0, 'new');"));
|
||||
"VALUES ('new', 0, 0, 0, 1, %1, 'new');").arg(QString::number(account_id)));
|
||||
|
||||
if (!q.exec()) {
|
||||
throw ApplicationException(q.lastError().text());
|
||||
@ -1786,67 +1821,6 @@ bool DatabaseQueries::deleteCategory(const QSqlDatabase& db, int id) {
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
int DatabaseQueries::addCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title,
|
||||
const QString& description, const QDateTime& creation_date, const QIcon& icon,
|
||||
bool* ok) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare("INSERT INTO Categories "
|
||||
"(parent_id, title, description, date_created, icon, account_id) "
|
||||
"VALUES (:parent_id, :title, :description, :date_created, :icon, :account_id);");
|
||||
q.bindValue(QSL(":parent_id"), parent_id);
|
||||
q.bindValue(QSL(":title"), title);
|
||||
q.bindValue(QSL(":description"), description);
|
||||
q.bindValue(QSL(":date_created"), creation_date.toMSecsSinceEpoch());
|
||||
q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon));
|
||||
q.bindValue(QSL(":account_id"), account_id);
|
||||
|
||||
if (!q.exec()) {
|
||||
qDebugNN << LOGSEC_DB
|
||||
<< "Failed to add category to database: '"
|
||||
<< q.lastError().text()
|
||||
<< "'.";
|
||||
|
||||
if (ok != nullptr) {
|
||||
*ok = false;
|
||||
}
|
||||
|
||||
// Query failed.
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if (ok != nullptr) {
|
||||
*ok = true;
|
||||
}
|
||||
|
||||
int new_id = q.lastInsertId().toInt();
|
||||
|
||||
// Now set custom ID in the DB.
|
||||
q.prepare(QSL("UPDATE Categories SET custom_id = :custom_id WHERE id = :id;"));
|
||||
q.bindValue(QSL(":custom_id"), QString::number(new_id));
|
||||
q.bindValue(QSL(":id"), new_id);
|
||||
q.exec();
|
||||
return new_id;
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseQueries::editCategory(const QSqlDatabase& db, int parent_id, int category_id,
|
||||
const QString& title, const QString& description, const QIcon& icon) {
|
||||
QSqlQuery q(db);
|
||||
|
||||
q.setForwardOnly(true);
|
||||
q.prepare("UPDATE Categories "
|
||||
"SET title = :title, description = :description, icon = :icon, parent_id = :parent_id "
|
||||
"WHERE id = :id;");
|
||||
q.bindValue(QSL(":title"), title);
|
||||
q.bindValue(QSL(":description"), description);
|
||||
q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon));
|
||||
q.bindValue(QSL(":parent_id"), parent_id);
|
||||
q.bindValue(QSL(":id"), category_id);
|
||||
return q.exec();
|
||||
}
|
||||
|
||||
MessageFilter* DatabaseQueries::addMessageFilter(const QSqlDatabase& db, const QString& title,
|
||||
const QString& script) {
|
||||
if (!db.driver()->hasFeature(QSqlDriver::DriverFeature::LastInsertId)) {
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "services/abstract/category.h"
|
||||
#include "services/abstract/label.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
#include "services/standard/standardfeed.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
@ -112,6 +111,10 @@ class DatabaseQueries {
|
||||
static bool cleanImportantMessages(const QSqlDatabase& db, bool clean_read_only, int account_id);
|
||||
static bool cleanFeeds(const QSqlDatabase& db, const QStringList& ids, bool clean_read_only, int account_id);
|
||||
static bool storeAccountTree(const QSqlDatabase& db, RootItem* tree_root, int account_id);
|
||||
static void createOverwriteFeed(const QSqlDatabase& db, Feed* feed, int account_id, int parent_id);
|
||||
static void createOverwriteCategory(const QSqlDatabase& db, Category* category, int account_id, int parent_id);
|
||||
static bool deleteFeed(const QSqlDatabase& db, int feed_custom_id, int account_id);
|
||||
static bool deleteCategory(const QSqlDatabase& db, int id);
|
||||
|
||||
template<typename T>
|
||||
static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr);
|
||||
@ -132,19 +135,6 @@ class DatabaseQueries {
|
||||
static void updateMessageFilter(const QSqlDatabase& db, MessageFilter* filter, bool* ok = nullptr);
|
||||
static void removeMessageFilterFromFeed(const QSqlDatabase& db, const QString& feed_custom_id, int filter_id,
|
||||
int account_id, bool* ok = nullptr);
|
||||
static void createOverwriteFeed(const QSqlDatabase& db, Feed* feed, int account_id, int parent_id);
|
||||
static bool deleteFeed(const QSqlDatabase& db, int feed_custom_id, int account_id);
|
||||
static bool deleteCategory(const QSqlDatabase& db, int id);
|
||||
|
||||
// Standard account.
|
||||
static int addCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title,
|
||||
const QString& description, const QDateTime& creation_date, const QIcon& icon,
|
||||
bool* ok = nullptr);
|
||||
static bool editCategory(const QSqlDatabase& db, int parent_id, int category_id,
|
||||
const QString& title, const QString& description, const QIcon& icon);
|
||||
|
||||
template<typename T>
|
||||
static void fillFeedData(T* feed, const QSqlRecord& sql_record);
|
||||
|
||||
// Gmail account.
|
||||
static QStringList getAllRecipients(const QSqlDatabase& db, int account_id);
|
||||
@ -155,18 +145,6 @@ class DatabaseQueries {
|
||||
explicit DatabaseQueries() = default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void DatabaseQueries::fillFeedData(T* feed, const QSqlRecord& sql_record) {
|
||||
Q_UNUSED(feed)
|
||||
Q_UNUSED(sql_record)
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void DatabaseQueries::fillFeedData(StandardFeed* feed, const QSqlRecord& sql_record) {
|
||||
Q_UNUSED(feed)
|
||||
Q_UNUSED(sql_record)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QList<ServiceRoot*> DatabaseQueries::getAccounts(const QSqlDatabase& db, const QString& code, bool* ok) {
|
||||
QSqlQuery query(db);
|
||||
@ -281,6 +259,9 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
|
||||
|
||||
Feed* feed = new T(query.record());
|
||||
|
||||
// Load custom data.
|
||||
feed->setCustomDatabaseData(deserializeCustomData(query.value(QSL("custom_data")).toString()));
|
||||
|
||||
if (filters_in_feeds.contains(feed->customId())) {
|
||||
auto all_filters_for_this_feed = filters_in_feeds.values(feed->customId());
|
||||
|
||||
@ -291,8 +272,6 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db,
|
||||
}
|
||||
}
|
||||
|
||||
fillFeedData<T>(static_cast<T*>(feed), query.record());
|
||||
|
||||
pair.second = feed;
|
||||
|
||||
feeds << pair;
|
||||
|
@ -28,7 +28,7 @@ Feed::Feed(RootItem* parent)
|
||||
Feed::Feed(const QSqlRecord& record) : Feed(nullptr) {
|
||||
setTitle(record.value(FDS_DB_TITLE_INDEX).toString());
|
||||
setId(record.value(FDS_DB_ID_INDEX).toInt());
|
||||
setSource(record.value(FDS_DB_URL_INDEX).toString());
|
||||
setSource(record.value(FDS_DB_SOURCE_INDEX).toString());
|
||||
setCustomId(record.value(FDS_DB_CUSTOM_ID_INDEX).toString());
|
||||
|
||||
if (customId().isEmpty()) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#include "services/standard/gui/formstandardcategorydetails.h"
|
||||
#include "services/abstract/gui/formcategorydetails.h"
|
||||
|
||||
#include "core/feedsmodel.h"
|
||||
#include "definitions/definitions.h"
|
||||
@ -8,12 +8,10 @@
|
||||
#include "gui/feedsview.h"
|
||||
#include "gui/messagebox.h"
|
||||
#include "gui/systemtrayicon.h"
|
||||
#include "miscellaneous/databasequeries.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "services/abstract/category.h"
|
||||
#include "services/abstract/rootitem.h"
|
||||
#include "services/standard/definitions.h"
|
||||
#include "services/standard/standardcategory.h"
|
||||
#include "services/standard/standardserviceroot.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDialogButtonBox>
|
||||
@ -24,8 +22,8 @@
|
||||
#include <QTextEdit>
|
||||
#include <QToolButton>
|
||||
|
||||
FormStandardCategoryDetails::FormStandardCategoryDetails(StandardServiceRoot* service_root, QWidget* parent)
|
||||
: QDialog(parent), m_editableCategory(nullptr), m_serviceRoot(service_root) {
|
||||
FormCategoryDetails::FormCategoryDetails(ServiceRoot* service_root, RootItem* parent_to_select, QWidget* parent)
|
||||
: QDialog(parent), m_category(nullptr), m_serviceRoot(service_root), m_parentToSelect(parent_to_select) {
|
||||
initialize();
|
||||
createConnections();
|
||||
|
||||
@ -34,37 +32,27 @@ FormStandardCategoryDetails::FormStandardCategoryDetails(StandardServiceRoot* se
|
||||
onDescriptionChanged(QString());
|
||||
}
|
||||
|
||||
FormStandardCategoryDetails::~FormStandardCategoryDetails() {
|
||||
FormCategoryDetails::~FormCategoryDetails() {
|
||||
qDebugNN << LOGSEC_GUI << "Destroying FormCategoryDetails instance.";
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::createConnections() {
|
||||
void FormCategoryDetails::createConnections() {
|
||||
// General connections.
|
||||
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormStandardCategoryDetails::apply);
|
||||
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormCategoryDetails::apply);
|
||||
connect(m_ui->m_txtTitle->lineEdit(), &BaseLineEdit::textChanged,
|
||||
this, &FormStandardCategoryDetails::onTitleChanged);
|
||||
this, &FormCategoryDetails::onTitleChanged);
|
||||
connect(m_ui->m_txtDescription->lineEdit(), &BaseLineEdit::textChanged,
|
||||
this, &FormStandardCategoryDetails::onDescriptionChanged);
|
||||
this, &FormCategoryDetails::onDescriptionChanged);
|
||||
|
||||
// Icon connections.
|
||||
connect(m_actionLoadIconFromFile, &QAction::triggered, this, &FormStandardCategoryDetails::onLoadIconFromFile);
|
||||
connect(m_actionUseDefaultIcon, &QAction::triggered, this, &FormStandardCategoryDetails::onUseDefaultIcon);
|
||||
connect(m_actionLoadIconFromFile, &QAction::triggered, this, &FormCategoryDetails::onLoadIconFromFile);
|
||||
connect(m_actionUseDefaultIcon, &QAction::triggered, this, &FormCategoryDetails::onUseDefaultIcon);
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::setEditableCategory(StandardCategory* editable_category) {
|
||||
m_editableCategory = editable_category;
|
||||
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) editable_category->parent())));
|
||||
m_ui->m_txtTitle->lineEdit()->setText(editable_category->title());
|
||||
m_ui->m_txtDescription->lineEdit()->setText(editable_category->description());
|
||||
m_ui->m_btnIcon->setIcon(editable_category->icon());
|
||||
}
|
||||
void FormCategoryDetails::loadCategoryData() {
|
||||
loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot, m_category);
|
||||
|
||||
int FormStandardCategoryDetails::addEditCategory(StandardCategory* input_category, RootItem* parent_to_select) {
|
||||
// Load categories.
|
||||
loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot, input_category);
|
||||
|
||||
if (input_category == nullptr) {
|
||||
// User is adding new category.
|
||||
if (m_creatingNew) {
|
||||
setWindowTitle(tr("Add new category"));
|
||||
|
||||
// Make sure that "default" icon is used as the default option for new
|
||||
@ -72,12 +60,12 @@ int FormStandardCategoryDetails::addEditCategory(StandardCategory* input_categor
|
||||
m_actionUseDefaultIcon->trigger();
|
||||
|
||||
// Load parent from suggested item.
|
||||
if (parent_to_select != nullptr) {
|
||||
if (parent_to_select->kind() == RootItem::Kind::Category) {
|
||||
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select)));
|
||||
if (m_parentToSelect != nullptr) {
|
||||
if (m_parentToSelect->kind() == RootItem::Kind::Category) {
|
||||
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) m_parentToSelect)));
|
||||
}
|
||||
else if (parent_to_select->kind() == RootItem::Kind::Feed) {
|
||||
int target_item = m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select->parent()));
|
||||
else if (m_parentToSelect->kind() == RootItem::Kind::Feed) {
|
||||
int target_item = m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) m_parentToSelect->parent()));
|
||||
|
||||
if (target_item >= 0) {
|
||||
m_ui->m_cmbParentCategory->setCurrentIndex(target_item);
|
||||
@ -86,68 +74,42 @@ int FormStandardCategoryDetails::addEditCategory(StandardCategory* input_categor
|
||||
}
|
||||
}
|
||||
else {
|
||||
// User is editing existing category.
|
||||
setWindowTitle(tr("Edit existing category"));
|
||||
setEditableCategory(input_category);
|
||||
setWindowTitle(tr("Edit '%1'").arg(m_category->title()));
|
||||
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) m_category->parent())));
|
||||
}
|
||||
|
||||
// Run the dialog.
|
||||
return QDialog::exec();
|
||||
m_ui->m_txtTitle->lineEdit()->setText(m_category->title());
|
||||
m_ui->m_txtDescription->lineEdit()->setText(m_category->description());
|
||||
m_ui->m_btnIcon->setIcon(m_category->icon());
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::apply() {
|
||||
void FormCategoryDetails::apply() {
|
||||
RootItem* parent = static_cast<RootItem*>(m_ui->m_cmbParentCategory->itemData(m_ui->m_cmbParentCategory->currentIndex()).value<void*>());
|
||||
auto* new_category = new StandardCategory();
|
||||
|
||||
new_category->setTitle(m_ui->m_txtTitle->lineEdit()->text());
|
||||
new_category->setCreationDate(QDateTime::currentDateTime());
|
||||
new_category->setDescription(m_ui->m_txtDescription->lineEdit()->text());
|
||||
new_category->setIcon(m_ui->m_btnIcon->icon());
|
||||
m_category->setTitle(m_ui->m_txtTitle->lineEdit()->text());
|
||||
m_category->setCreationDate(QDateTime::currentDateTime());
|
||||
m_category->setDescription(m_ui->m_txtDescription->lineEdit()->text());
|
||||
m_category->setIcon(m_ui->m_btnIcon->icon());
|
||||
|
||||
if (m_editableCategory == nullptr) {
|
||||
// Add the category.
|
||||
if (new_category->addItself(parent)) {
|
||||
m_serviceRoot->requestItemReassignment(new_category, parent);
|
||||
accept();
|
||||
}
|
||||
else {
|
||||
delete new_category;
|
||||
qApp->showGuiMessage(tr("Cannot add category"),
|
||||
tr("Category was not added due to error."),
|
||||
QSystemTrayIcon::MessageIcon::Critical,
|
||||
qApp->mainFormWidget(), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
new_category->setParent(parent);
|
||||
bool edited = m_editableCategory->editItself(new_category);
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
|
||||
if (edited) {
|
||||
m_serviceRoot->requestItemReassignment(m_editableCategory, new_category->parent());
|
||||
accept();
|
||||
}
|
||||
else {
|
||||
qApp->showGuiMessage(tr("Cannot edit category"),
|
||||
tr("Category was not edited due to error."),
|
||||
QSystemTrayIcon::Critical, this, true);
|
||||
}
|
||||
|
||||
delete new_category;
|
||||
}
|
||||
DatabaseQueries::createOverwriteCategory(database, m_category, m_serviceRoot->accountId(), parent->id());
|
||||
m_serviceRoot->requestItemReassignment(m_category, parent);
|
||||
accept();
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::onTitleChanged(const QString& new_title) {
|
||||
if (new_title.simplified().size() >= MIN_CATEGORY_NAME_LENGTH) {
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
void FormCategoryDetails::onTitleChanged(const QString& new_title) {
|
||||
if (!new_title.simplified().isEmpty()) {
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(true);
|
||||
m_ui->m_txtTitle->setStatus(WidgetWithStatus::StatusType::Ok, tr("Category name is ok."));
|
||||
}
|
||||
else {
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(false);
|
||||
m_ui->m_txtTitle->setStatus(WidgetWithStatus::StatusType::Error, tr("Category name is too short."));
|
||||
}
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::onDescriptionChanged(const QString& new_description) {
|
||||
void FormCategoryDetails::onDescriptionChanged(const QString& new_description) {
|
||||
if (new_description.simplified().isEmpty()) {
|
||||
m_ui->m_txtDescription->setStatus(LineEditWithStatus::StatusType::Warning, tr("Description is empty."));
|
||||
}
|
||||
@ -156,7 +118,7 @@ void FormStandardCategoryDetails::onDescriptionChanged(const QString& new_descri
|
||||
}
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::onLoadIconFromFile() {
|
||||
void FormCategoryDetails::onLoadIconFromFile() {
|
||||
QFileDialog dialog(this, tr("Select icon file for the category"),
|
||||
qApp->homeFolder(), tr("Images (*.bmp *.jpg *.jpeg *.png *.svg *.tga)"));
|
||||
|
||||
@ -177,12 +139,12 @@ void FormStandardCategoryDetails::onLoadIconFromFile() {
|
||||
}
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::onUseDefaultIcon() {
|
||||
void FormCategoryDetails::onUseDefaultIcon() {
|
||||
m_ui->m_btnIcon->setIcon(QIcon());
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::initialize() {
|
||||
m_ui.reset(new Ui::FormStandardCategoryDetails());
|
||||
void FormCategoryDetails::initialize() {
|
||||
m_ui.reset(new Ui::FormCategoryDetails());
|
||||
m_ui->setupUi(this);
|
||||
|
||||
// Set text boxes.
|
||||
@ -196,7 +158,7 @@ void FormStandardCategoryDetails::initialize() {
|
||||
setWindowIcon(qApp->icons()->fromTheme(QSL("folder")));
|
||||
|
||||
// Setup button box.
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(false);
|
||||
|
||||
// Setup menu & actions for icon selection.
|
||||
m_iconMenu = new QMenu(tr("Icon selection"), this);
|
||||
@ -218,9 +180,9 @@ void FormStandardCategoryDetails::initialize() {
|
||||
m_ui->m_txtTitle->lineEdit()->setFocus(Qt::TabFocusReason);
|
||||
}
|
||||
|
||||
void FormStandardCategoryDetails::loadCategories(const QList<Category*>& categories,
|
||||
RootItem* root_item,
|
||||
StandardCategory* input_category) {
|
||||
void FormCategoryDetails::loadCategories(const QList<Category*>& categories,
|
||||
RootItem* root_item,
|
||||
Category* input_category) {
|
||||
m_ui->m_cmbParentCategory->addItem(root_item->icon(),
|
||||
root_item->title(),
|
||||
QVariant::fromValue((void*) root_item));
|
96
src/librssguard/services/abstract/gui/formcategorydetails.h
Normal file
96
src/librssguard/services/abstract/gui/formcategorydetails.h
Normal file
@ -0,0 +1,96 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef FORMCATEGORYDETAILS_H
|
||||
#define FORMCATEGORYDETAILS_H
|
||||
|
||||
#include "ui_formcategorydetails.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class FormCategoryDetails;
|
||||
}
|
||||
|
||||
class Category;
|
||||
class ServiceRoot;
|
||||
class FeedsModel;
|
||||
class RootItem;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
class FormCategoryDetails : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FormCategoryDetails(ServiceRoot* service_root, RootItem* parent_to_select = nullptr, QWidget* parent = nullptr);
|
||||
virtual ~FormCategoryDetails();
|
||||
|
||||
template<class T>
|
||||
T* addEditCategory(T* category_to_edit = nullptr);
|
||||
|
||||
template<class T>
|
||||
T* category() const;
|
||||
|
||||
protected:
|
||||
virtual void loadCategoryData();
|
||||
|
||||
protected slots:
|
||||
virtual void apply();
|
||||
|
||||
private slots:
|
||||
|
||||
// Trigerred when title/description changes.
|
||||
void onTitleChanged(const QString& new_title);
|
||||
void onDescriptionChanged(const QString& new_description);
|
||||
|
||||
// Icon selectors.
|
||||
void onLoadIconFromFile();
|
||||
void onUseDefaultIcon();
|
||||
|
||||
private:
|
||||
void createConnections();
|
||||
void initialize();
|
||||
|
||||
// Loads categories into the dialog + give root "category"
|
||||
// and make sure that no childs of input category (including)
|
||||
// input category are loaded.
|
||||
void loadCategories(const QList<Category*>& categories, RootItem* root_item, Category* input_category);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::FormCategoryDetails> m_ui;
|
||||
Category* m_category;
|
||||
ServiceRoot* m_serviceRoot;
|
||||
QMenu* m_iconMenu{};
|
||||
QAction* m_actionLoadIconFromFile{};
|
||||
QAction* m_actionUseDefaultIcon{};
|
||||
RootItem* m_parentToSelect;
|
||||
bool m_creatingNew;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline T* FormCategoryDetails::addEditCategory(T* category_to_edit) {
|
||||
m_creatingNew = category_to_edit == nullptr;
|
||||
|
||||
if (m_creatingNew) {
|
||||
m_category = new T();
|
||||
}
|
||||
else {
|
||||
m_category = category_to_edit;
|
||||
}
|
||||
|
||||
loadCategoryData();
|
||||
|
||||
if (exec() == QDialog::DialogCode::Accepted) {
|
||||
return category<T>();
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T* FormCategoryDetails::category() const {
|
||||
return qobject_cast<T*>(m_category);
|
||||
}
|
||||
|
||||
#endif // FORMCATEGORYDETAILS_H
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FormStandardCategoryDetails</class>
|
||||
<widget class="QDialog" name="FormStandardCategoryDetails">
|
||||
<class>FormCategoryDetails</class>
|
||||
<widget class="QDialog" name="FormCategoryDetails">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@ -153,7 +153,7 @@
|
||||
<connection>
|
||||
<sender>m_buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>FormStandardCategoryDetails</receiver>
|
||||
<receiver>FormCategoryDetails</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
@ -3,7 +3,6 @@
|
||||
|
||||
#define DEFAULT_FEED_ENCODING "UTF-8"
|
||||
#define DEFAULT_FEED_TYPE "RSS"
|
||||
#define MIN_CATEGORY_NAME_LENGTH 1
|
||||
#define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml"
|
||||
|
||||
#endif // STANDARD_DEFINITIONS_H
|
||||
|
@ -1,72 +0,0 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef FORMCATEGORYDETAILS_H
|
||||
#define FORMCATEGORYDETAILS_H
|
||||
|
||||
#include "ui_formstandardcategorydetails.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class FormStandardCategoryDetails;
|
||||
}
|
||||
|
||||
class Category;
|
||||
class StandardCategory;
|
||||
class StandardServiceRoot;
|
||||
class FeedsModel;
|
||||
class RootItem;
|
||||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
class FormStandardCategoryDetails : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FormStandardCategoryDetails(StandardServiceRoot* service_root, QWidget* parent = nullptr);
|
||||
virtual ~FormStandardCategoryDetails();
|
||||
|
||||
public slots:
|
||||
|
||||
// Executes add/edit standard category dialog.
|
||||
int addEditCategory(StandardCategory* input_category, RootItem* parent_to_select);
|
||||
|
||||
protected slots:
|
||||
|
||||
// Applies changes.
|
||||
void apply();
|
||||
|
||||
// Trigerred when title/description changes.
|
||||
void onTitleChanged(const QString& new_title);
|
||||
void onDescriptionChanged(const QString& new_description);
|
||||
|
||||
// Icon selectors.
|
||||
void onLoadIconFromFile();
|
||||
void onUseDefaultIcon();
|
||||
|
||||
protected:
|
||||
|
||||
// Creates needed connections.
|
||||
void createConnections();
|
||||
|
||||
// Sets the category which will be edited.
|
||||
void setEditableCategory(StandardCategory* editable_category);
|
||||
|
||||
// Initializes the dialog.
|
||||
void initialize();
|
||||
|
||||
// Loads categories into the dialog + give root "category"
|
||||
// and make sure that no childs of input category (including)
|
||||
// input category are loaded.
|
||||
void loadCategories(const QList<Category*>& categories, RootItem* root_item, StandardCategory* input_category);
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::FormStandardCategoryDetails> m_ui;
|
||||
StandardCategory* m_editableCategory;
|
||||
StandardServiceRoot* m_serviceRoot;
|
||||
QMenu* m_iconMenu{};
|
||||
QAction* m_actionLoadIconFromFile{};
|
||||
QAction* m_actionUseDefaultIcon{};
|
||||
};
|
||||
|
||||
#endif // FORMCATEGORYDETAILS_H
|
@ -25,9 +25,9 @@ FormStandardImportExport::FormStandardImportExport(StandardServiceRoot* service_
|
||||
connect(m_model, &FeedsImportExportModel::parsingProgress, this, &FormStandardImportExport::onParsingProgress);
|
||||
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
|
||||
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::StatusType::Error, tr("No file is selected."), tr("No file is selected."));
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->disconnect();
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->disconnect();
|
||||
m_ui->m_lblResult->setStatus(WidgetWithStatus::StatusType::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
|
||||
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormStandardImportExport::performAction);
|
||||
connect(m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok), &QPushButton::clicked, this, &FormStandardImportExport::performAction);
|
||||
connect(m_ui->m_btnSelectFile, &QPushButton::clicked, this, &FormStandardImportExport::selectFile);
|
||||
connect(m_ui->m_btnCheckAllItems, &QPushButton::clicked, m_model, &FeedsImportExportModel::checkAllItems);
|
||||
connect(m_ui->m_btnUncheckAllItems, &QPushButton::clicked, m_model, &FeedsImportExportModel::uncheckAllItems);
|
||||
@ -72,7 +72,7 @@ void FormStandardImportExport::setMode(const FeedsImportExportModel::Mode& mode)
|
||||
break;
|
||||
}
|
||||
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(false);
|
||||
}
|
||||
|
||||
void FormStandardImportExport::selectFile() {
|
||||
@ -97,7 +97,7 @@ void FormStandardImportExport::onParsingStarted() {
|
||||
m_ui->m_groupFeeds->setEnabled(false);
|
||||
m_ui->m_progressBar->setValue(0);
|
||||
m_ui->m_progressBar->setVisible(true);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(false);
|
||||
}
|
||||
|
||||
void FormStandardImportExport::onParsingFinished(int count_failed, int count_succeeded, bool parsing_error) {
|
||||
@ -121,7 +121,7 @@ void FormStandardImportExport::onParsingFinished(int count_failed, int count_suc
|
||||
tr("Error occurred. File is not well-formed. Select another file."));
|
||||
}
|
||||
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(true);
|
||||
}
|
||||
|
||||
void FormStandardImportExport::onParsingProgress(int completed, int total) {
|
||||
@ -161,7 +161,7 @@ void FormStandardImportExport::selectExportFile() {
|
||||
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::StatusType::Ok, QDir::toNativeSeparators(selected_file), tr("File is selected."));
|
||||
}
|
||||
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_ui->m_lblSelectFile->status() == WidgetWithStatus::StatusType::Ok);
|
||||
m_ui->m_buttonBox->button(QDialogButtonBox::StandardButton::Ok)->setEnabled(m_ui->m_lblSelectFile->status() == WidgetWithStatus::StatusType::Ok);
|
||||
}
|
||||
|
||||
void FormStandardImportExport::selectImportFile() {
|
||||
|
@ -200,7 +200,7 @@ void StandardFeedDetails::guessFeed(StandardFeed::SourceType source_type, const
|
||||
}
|
||||
|
||||
void StandardFeedDetails::onTitleChanged(const QString& new_title) {
|
||||
if (new_title.simplified().size() >= MIN_CATEGORY_NAME_LENGTH) {
|
||||
if (!new_title.simplified().isEmpty()) {
|
||||
m_ui.m_txtTitle->setStatus(LineEditWithStatus::StatusType::Ok, tr("Feed name is ok."));
|
||||
}
|
||||
else {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "miscellaneous/settings.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "services/standard/gui/formstandardcategorydetails.h"
|
||||
#include "services/abstract/gui/formcategorydetails.h"
|
||||
#include "services/standard/standardfeed.h"
|
||||
#include "services/standard/standardserviceroot.h"
|
||||
|
||||
@ -27,20 +27,11 @@ Qt::ItemFlags StandardCategory::additionalFlags() const {
|
||||
}
|
||||
|
||||
bool StandardCategory::performDragDropChange(RootItem* target_item) {
|
||||
auto* category_new = new StandardCategory(*this);
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
|
||||
category_new->clearChildren();
|
||||
category_new->setParent(target_item);
|
||||
|
||||
if (editItself(category_new)) {
|
||||
serviceRoot()->requestItemReassignment(this, target_item);
|
||||
delete category_new;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
delete category_new;
|
||||
return false;
|
||||
}
|
||||
DatabaseQueries::createOverwriteCategory(database, this, getParentServiceRoot()->accountId(), target_item->id());
|
||||
serviceRoot()->requestItemReassignment(this, target_item);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StandardCategory::canBeEdited() const {
|
||||
@ -52,10 +43,11 @@ bool StandardCategory::canBeDeleted() const {
|
||||
}
|
||||
|
||||
bool StandardCategory::editViaGui() {
|
||||
QScopedPointer<FormStandardCategoryDetails> form_pointer(new FormStandardCategoryDetails(serviceRoot(),
|
||||
qApp->mainFormWidget()));
|
||||
QScopedPointer<FormCategoryDetails> form_pointer(new FormCategoryDetails(serviceRoot(),
|
||||
nullptr,
|
||||
qApp->mainFormWidget()));
|
||||
|
||||
form_pointer->addEditCategory(this, nullptr);
|
||||
form_pointer->addEditCategory(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -94,41 +86,4 @@ bool StandardCategory::removeItself() {
|
||||
}
|
||||
}
|
||||
|
||||
bool StandardCategory::addItself(RootItem* parent) {
|
||||
// Now, add category to persistent storage.
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
int new_id = DatabaseQueries::addCategory(database, parent->id(), parent->getParentServiceRoot()->accountId(),
|
||||
title(), description(), creationDate(), icon());
|
||||
|
||||
if (new_id <= 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
setId(new_id);
|
||||
setCustomId(QString::number(new_id));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool StandardCategory::editItself(StandardCategory* new_category_data) {
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
StandardCategory* original_category = this;
|
||||
RootItem* new_parent = new_category_data->parent();
|
||||
|
||||
if (DatabaseQueries::editCategory(database, new_parent->id(), original_category->id(),
|
||||
new_category_data->title(), new_category_data->description(),
|
||||
new_category_data->icon())) {
|
||||
// Setup new model data for the original item.
|
||||
original_category->setDescription(new_category_data->description());
|
||||
original_category->setIcon(new_category_data->icon());
|
||||
original_category->setTitle(new_category_data->title());
|
||||
|
||||
// Editing is done.
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
StandardCategory::StandardCategory(const QSqlRecord& record) : Category(record) {}
|
||||
|
@ -35,8 +35,6 @@ class StandardCategory : public Category {
|
||||
bool editViaGui();
|
||||
bool deleteViaGui();
|
||||
|
||||
bool addItself(RootItem* parent);
|
||||
bool editItself(StandardCategory* new_category_data);
|
||||
bool removeItself();
|
||||
};
|
||||
|
||||
|
@ -59,6 +59,10 @@ StandardFeed::StandardFeed(const StandardFeed& other)
|
||||
m_password = other.password();
|
||||
}
|
||||
|
||||
StandardFeed::StandardFeed(const QSqlRecord& record) : Feed(record) {
|
||||
m_networkError = QNetworkReply::NetworkError::NoError;
|
||||
}
|
||||
|
||||
StandardFeed::~StandardFeed() {
|
||||
qDebugNN << LOGSEC_CORE << "Destroying StandardFeed instance.";
|
||||
}
|
||||
@ -740,34 +744,3 @@ QString StandardFeed::postProcessFeedFileWithScript(const QString& execution_lin
|
||||
QNetworkReply::NetworkError StandardFeed::networkError() const {
|
||||
return m_networkError;
|
||||
}
|
||||
|
||||
StandardFeed::StandardFeed(const QSqlRecord& record) : Feed(record) {
|
||||
setEncoding(record.value(FDS_DB_ENCODING_INDEX).toString());
|
||||
setSourceType(SourceType(record.value(FDS_DB_SOURCE_TYPE_INDEX).toInt()));
|
||||
setPostProcessScript(record.value(FDS_DB_POST_PROCESS).toString());
|
||||
|
||||
setPasswordProtected(record.value(FDS_DB_PROTECTED_INDEX).toBool());
|
||||
setUsername(record.value(FDS_DB_USERNAME_INDEX).toString());
|
||||
|
||||
if (record.value(FDS_DB_PASSWORD_INDEX).toString().isEmpty()) {
|
||||
setPassword(record.value(FDS_DB_PASSWORD_INDEX).toString());
|
||||
}
|
||||
else {
|
||||
setPassword(TextFactory::decrypt(record.value(FDS_DB_PASSWORD_INDEX).toString()));
|
||||
}
|
||||
|
||||
StandardFeed::Type type = static_cast<StandardFeed::Type>(record.value(FDS_DB_TYPE_INDEX).toInt());
|
||||
|
||||
switch (type) {
|
||||
case StandardFeed::Type::Atom10:
|
||||
case StandardFeed::Type::Rdf:
|
||||
case StandardFeed::Type::Rss0X:
|
||||
case StandardFeed::Type::Rss2X:
|
||||
case StandardFeed::Type::Json: {
|
||||
setType(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_networkError = QNetworkReply::NetworkError::NoError;
|
||||
}
|
||||
|
@ -11,12 +11,12 @@
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "miscellaneous/mutex.h"
|
||||
#include "miscellaneous/settings.h"
|
||||
#include "services/abstract/gui/formcategorydetails.h"
|
||||
#include "services/abstract/importantnode.h"
|
||||
#include "services/abstract/labelsnode.h"
|
||||
#include "services/abstract/recyclebin.h"
|
||||
#include "services/standard/definitions.h"
|
||||
#include "services/standard/gui/formeditstandardaccount.h"
|
||||
#include "services/standard/gui/formstandardcategorydetails.h"
|
||||
#include "services/standard/gui/formstandardfeeddetails.h"
|
||||
#include "services/standard/gui/formstandardimportexport.h"
|
||||
#include "services/standard/standardcategory.h"
|
||||
@ -208,16 +208,16 @@ bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel* model,
|
||||
// Add category to model.
|
||||
new_category->clearChildren();
|
||||
|
||||
if (new_category->addItself(target_parent)) {
|
||||
QSqlDatabase database = qApp->database()->connection(metaObject()->className());
|
||||
|
||||
try {
|
||||
DatabaseQueries::createOverwriteCategory(database,
|
||||
new_category,
|
||||
target_root_node->getParentServiceRoot()->accountId(),
|
||||
target_parent->id());
|
||||
requestItemReassignment(new_category, target_parent);
|
||||
|
||||
// Process all children of this category.
|
||||
original_parents.push(new_category);
|
||||
new_parents.push(source_category);
|
||||
}
|
||||
else {
|
||||
delete new_category;
|
||||
|
||||
catch (ApplicationException& ex) {
|
||||
// Add category failed, but this can mean that the same category (with same title)
|
||||
// already exists. If such a category exists in current parent, then find it and
|
||||
// add descendants to it.
|
||||
@ -275,10 +275,11 @@ void StandardServiceRoot::addNewCategory(RootItem* selected_item) {
|
||||
return;
|
||||
}
|
||||
|
||||
QScopedPointer<FormStandardCategoryDetails> form_pointer(new FormStandardCategoryDetails(this,
|
||||
qApp->mainFormWidget()));
|
||||
QScopedPointer<FormCategoryDetails> form_pointer(new FormCategoryDetails(this,
|
||||
selected_item,
|
||||
qApp->mainFormWidget()));
|
||||
|
||||
form_pointer->addEditCategory(nullptr, selected_item);
|
||||
form_pointer->addEditCategory<StandardCategory>();
|
||||
qApp->feedUpdateLock()->unlock();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user