Save work on DB layer and DB models.

This commit is contained in:
Martin Rotter 2021-03-02 14:30:13 +01:00
parent 8e2eede3ed
commit f29ea98bbb
24 changed files with 265 additions and 404 deletions

View File

@ -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,

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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()));

View File

@ -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);

View File

@ -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() &&

View File

@ -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"

View File

@ -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);
}
}

View File

@ -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 \

View File

@ -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)) {

View File

@ -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;

View File

@ -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()) {

View File

@ -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));

View 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

View File

@ -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">

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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 {

View File

@ -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) {}

View File

@ -35,8 +35,6 @@ class StandardCategory : public Category {
bool editViaGui();
bool deleteViaGui();
bool addItself(RootItem* parent);
bool editItself(StandardCategory* new_category_data);
bool removeItself();
};

View File

@ -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;
}

View File

@ -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();
}