diff --git a/resources/sql/db_init_sqlite.sql b/resources/sql/db_init_sqlite.sql index ef81e8fd1..64a720041 100644 --- a/resources/sql/db_init_sqlite.sql +++ b/resources/sql/db_init_sqlite.sql @@ -22,7 +22,7 @@ CREATE TABLE Categories ( parent_id INTEGER NOT NULL CHECK (parent_id >= -1), /* Root categories contain -1 here. */ title TEXT NOT NULL CHECK (title != ''), description TEXT, - date_created INTEGER, + date_created INTEGER NOT NULL CHECK (date_created >= 0), icon BLOB, account_id INTEGER NOT NULL, custom_id TEXT, @@ -34,14 +34,16 @@ CREATE TABLE Feeds ( id INTEGER PRIMARY KEY, title TEXT NOT NULL CHECK (title != ''), description TEXT, - date_created INTEGER, + date_created INTEGER NOT NULL CHECK (date_created >= 0), icon BLOB, category INTEGER NOT NULL CHECK (category >= -1), /* Root feeds contain -1 here. */ source TEXT, update_type INTEGER(1) NOT NULL CHECK (update_type >= 0), update_interval INTEGER NOT NULL DEFAULT 15 CHECK (update_interval >= 1), account_id INTEGER NOT NULL, - custom_id TEXT, + custom_id TEXT NOT NULL CHECK (custom_id != ''), /* Custom ID cannot be empty, it must contain either service-specific ID, or Feeds/id. */ + /* Custom column for (serialized) custom account-specific data. */ + custom_data TEXT, FOREIGN KEY (account_id) REFERENCES Accounts (id) ON DELETE CASCADE ); @@ -49,15 +51,15 @@ CREATE TABLE Feeds ( CREATE TABLE Messages ( id INTEGER PRIMARY KEY, is_read INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_read >= 0 AND is_read <= 1), - is_deleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_deleted >= 0 AND is_deleted <= 1), is_important INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_important >= 0 AND is_important <= 1), - feed TEXT NOT NULL, + 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. */ title TEXT NOT NULL CHECK (title != ''), url TEXT, author TEXT, - date_created INTEGER NOT NULL CHECK (date_created != 0), + date_created INTEGER NOT NULL CHECK (date_created >= 0), contents TEXT, - is_pdeleted INTEGER(1) NOT NULL DEFAULT 0 CHECK (is_pdeleted >= 0 AND is_pdeleted <= 1), enclosures TEXT, account_id INTEGER NOT NULL, custom_id TEXT, @@ -74,7 +76,7 @@ CREATE TABLE MessageFilters ( -- ! CREATE TABLE MessageFiltersInFeeds ( filter INTEGER NOT NULL, - feed_custom_id TEXT NOT NULL, + feed_custom_id TEXT NOT NULL, /* Points to Feeds/custom_id. */ account_id INTEGER NOT NULL, FOREIGN KEY (filter) REFERENCES MessageFilters (id) ON DELETE CASCADE, diff --git a/src/librssguard/gui/feedsview.cpp b/src/librssguard/gui/feedsview.cpp index 6a86df0e5..b3b77f09c 100755 --- a/src/librssguard/gui/feedsview.cpp +++ b/src/librssguard/gui/feedsview.cpp @@ -162,7 +162,7 @@ void FeedsView::addFeedIntoSelectedAccount() { ServiceRoot* root = selected->getParentServiceRoot(); if (root->supportsFeedAdding()) { - root->addNewFeed(selected); + root->addNewFeed(selected, QGuiApplication::clipboard()->text(QClipboard::Mode::Clipboard)); } else { qApp->showGuiMessage(tr("Not supported"), diff --git a/src/librssguard/miscellaneous/databasequeries.cpp b/src/librssguard/miscellaneous/databasequeries.cpp index 47b139096..99bb834d6 100755 --- a/src/librssguard/miscellaneous/databasequeries.cpp +++ b/src/librssguard/miscellaneous/databasequeries.cpp @@ -1483,47 +1483,57 @@ bool DatabaseQueries::storeAccountTree(const QSqlDatabase& db, RootItem* tree_ro QSqlQuery query_category(db); QSqlQuery query_feed(db); - query_category.setForwardOnly(true); - query_feed.setForwardOnly(true); - query_category.prepare("INSERT INTO Categories (parent_id, title, account_id, custom_id) " + // TODO: use createOvewriteAccount and createOverwriteFeed + +/* + query_category.setForwardOnly(true); + query_feed.setForwardOnly(true); + query_category.prepare("INSERT INTO Categories (parent_id, title, account_id, custom_id) " "VALUES (:parent_id, :title, :account_id, :custom_id);"); - query_feed.prepare("INSERT INTO Feeds (title, icon, url, category, protected, update_type, update_interval, account_id, custom_id) " + query_feed.prepare("INSERT INTO Feeds (title, icon, url, category, protected, update_type, update_interval, account_id, custom_id) " "VALUES (:title, :icon, :url, :category, :protected, :update_type, :update_interval, :account_id, :custom_id);"); + */ // Iterate all children. for (RootItem* child : tree_root->getSubTree()) { if (child->kind() == RootItem::Kind::Category) { - query_category.bindValue(QSL(":parent_id"), child->parent()->id()); - query_category.bindValue(QSL(":title"), child->title()); - query_category.bindValue(QSL(":account_id"), account_id); - query_category.bindValue(QSL(":custom_id"), child->customId()); + /* + query_category.bindValue(QSL(":parent_id"), child->parent()->id()); + query_category.bindValue(QSL(":title"), child->title()); + query_category.bindValue(QSL(":account_id"), account_id); + query_category.bindValue(QSL(":custom_id"), child->customId()); - if (query_category.exec()) { - child->setId(query_category.lastInsertId().toInt()); - } - else { - return false; - } + if (query_category.exec()) { + child->setId(query_category.lastInsertId().toInt()); + } + else { + return false; + } + */ } else if (child->kind() == RootItem::Kind::Feed) { - Feed* feed = child->toFeed(); + createOverwriteFeed(db, child->toFeed(), account_id, child->parent()->id()); - query_feed.bindValue(QSL(":title"), feed->title()); - query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); - query_feed.bindValue(QSL(":url"), feed->source()); - query_feed.bindValue(QSL(":category"), feed->parent()->id()); - query_feed.bindValue(QSL(":protected"), 0); - query_feed.bindValue(QSL(":update_type"), int(feed->autoUpdateType())); - query_feed.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval()); - query_feed.bindValue(QSL(":account_id"), account_id); - query_feed.bindValue(QSL(":custom_id"), feed->customId()); + /* + Feed* feed = child->toFeed(); - if (query_feed.exec()) { - feed->setId(query_feed.lastInsertId().toInt()); - } - else { - return false; - } + query_feed.bindValue(QSL(":title"), feed->title()); + query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); + query_feed.bindValue(QSL(":url"), feed->source()); + query_feed.bindValue(QSL(":category"), feed->parent()->id()); + query_feed.bindValue(QSL(":protected"), 0); + query_feed.bindValue(QSL(":update_type"), int(feed->autoUpdateType())); + query_feed.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval()); + query_feed.bindValue(QSL(":account_id"), account_id); + query_feed.bindValue(QSL(":custom_id"), feed->customId()); + + if (query_feed.exec()) { + feed->setId(query_feed.lastInsertId().toInt()); + } + else { + return false; + } + */ } else if (child->kind() == RootItem::Kind::Labels) { // Add all labels. @@ -1658,6 +1668,51 @@ QStringList DatabaseQueries::customIdsOfMessagesFromFeed(const QSqlDatabase& db, return ids; } +void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, int account_id, int parent_id) { + QSqlQuery q(db); + + if (feed->id() <= 0) { + // 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');")); + + if (!q.exec()) { + throw ApplicationException(q.lastError().text()); + } + else { + feed->setId(q.lastInsertId().toInt()); + } + } + + q.prepare("UPDATE Feeds " + "SET title = :title, description = :description, date_created = :date_created, " + " icon = :icon, category = :category, source = :source, update_type = :update_type, " + " update_interval = :update_interval, account_id = :account_id, " + " custom_id = :custom_id, custom_data = :custom_data " + "WHERE id = :id;"); + q.bindValue(QSL(":title"), feed->title()); + q.bindValue(QSL(":description"), feed->description()); + q.bindValue(QSL(":date_created"), feed->creationDate().toMSecsSinceEpoch()); + q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); + q.bindValue(QSL(":category"), parent_id); + q.bindValue(QSL(":source"), feed->source()); + q.bindValue(QSL(":update_type"), int(feed->autoUpdateType())); + q.bindValue(QSL(":update_interval"), feed->autoUpdateInitialInterval()); + q.bindValue(QSL(":account_id"), account_id); + q.bindValue(QSL(":custom_id"), feed->customId().isEmpty() ? QString::number(feed->id()) : feed->customId()); + q.bindValue(QSL(":id"), feed->id()); + + auto custom_data = feed->customDatabaseData(); + QString serialized_custom_data = serializeCustomData(custom_data); + + q.bindValue(QSL(":custom_data"), serialized_custom_data); + + if (!q.exec()) { + throw ApplicationException(q.lastError().text()); + } +} + void DatabaseQueries::createOverwriteAccount(const QSqlDatabase& db, ServiceRoot* account) { QSqlQuery q(db); @@ -1731,9 +1786,9 @@ bool DatabaseQueries::deleteCategory(const QSqlDatabase& db, int id) { return q.exec(); } -int DatabaseQueries::addStandardCategory(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, - bool* ok) { +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); @@ -1776,8 +1831,8 @@ int DatabaseQueries::addStandardCategory(const QSqlDatabase& db, int parent_id, } } -bool DatabaseQueries::editStandardCategory(const QSqlDatabase& db, int parent_id, int category_id, - const QString& title, const QString& description, const QIcon& icon) { +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); @@ -1792,145 +1847,6 @@ bool DatabaseQueries::editStandardCategory(const QSqlDatabase& db, int parent_id return q.exec(); } -int DatabaseQueries::addStandardFeed(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, - Feed::AutoUpdateType auto_update_type, int auto_update_interval, - StandardFeed::SourceType source_type, const QString& post_process_script, - StandardFeed::Type feed_format, bool* ok) { - QSqlQuery q(db); - - qDebug() << "Adding feed with title '" << title.toUtf8() << "' to DB."; - q.setForwardOnly(true); - q.prepare("INSERT INTO Feeds " - "(title, description, date_created, icon, category, encoding, url, source_type, post_process, protected, username, password, update_type, update_interval, type, account_id) " - "VALUES (:title, :description, :date_created, :icon, :category, :encoding, :url, :source_type, :post_process, :protected, :username, :password, :update_type, :update_interval, :type, :account_id);"); - q.bindValue(QSL(":title"), title.toUtf8()); - q.bindValue(QSL(":description"), description.toUtf8()); - q.bindValue(QSL(":date_created"), creation_date.toMSecsSinceEpoch()); - q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon)); - q.bindValue(QSL(":category"), parent_id); - q.bindValue(QSL(":encoding"), encoding); - q.bindValue(QSL(":url"), url); - q.bindValue(QSL(":source_type"), int(source_type)); - q.bindValue(QSL(":post_process"), post_process_script.simplified()); - q.bindValue(QSL(":protected"), is_protected ? 1 : 0); - q.bindValue(QSL(":username"), username); - q.bindValue(QSL(":account_id"), account_id); - - if (password.isEmpty()) { - q.bindValue(QSL(":password"), password); - } - else { - q.bindValue(QSL(":password"), TextFactory::encrypt(password)); - } - - q.bindValue(QSL(":update_type"), int(auto_update_type)); - q.bindValue(QSL(":update_interval"), auto_update_interval); - q.bindValue(QSL(":type"), int(feed_format)); - - if (q.exec()) { - int new_id = q.lastInsertId().toInt(); - - // Now set custom ID in the DB. - q.prepare(QSL("UPDATE Feeds 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(); - - if (ok != nullptr) { - *ok = true; - } - - return new_id; - } - else { - if (ok != nullptr) { - *ok = false; - } - - qWarningNN << LOGSEC_DB - << "Failed to add feed to database: '" - << q.lastError().text() - << "'."; - return 0; - } -} - -bool DatabaseQueries::editStandardFeed(const QSqlDatabase& db, int parent_id, int feed_id, const QString& title, - const QString& description, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, - Feed::AutoUpdateType auto_update_type, - int auto_update_interval, StandardFeed::SourceType source_type, - const QString& post_process_script, StandardFeed::Type feed_format) { - QSqlQuery q(db); - - q.setForwardOnly(true); - q.prepare("UPDATE Feeds " - "SET title = :title, description = :description, icon = :icon, category = :category, encoding = :encoding, url = :url, source_type = :source_type, post_process = :post_process, protected = :protected, username = :username, password = :password, update_type = :update_type, update_interval = :update_interval, type = :type " - "WHERE id = :id;"); - q.bindValue(QSL(":title"), title); - q.bindValue(QSL(":description"), description); - q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon)); - q.bindValue(QSL(":category"), parent_id); - q.bindValue(QSL(":encoding"), encoding); - q.bindValue(QSL(":url"), url); - q.bindValue(QSL(":source_type"), int(source_type)); - q.bindValue(QSL(":post_process"), post_process_script.simplified()); - q.bindValue(QSL(":protected"), is_protected ? 1 : 0); - q.bindValue(QSL(":username"), username); - - if (password.isEmpty()) { - q.bindValue(QSL(":password"), password); - } - else { - q.bindValue(QSL(":password"), TextFactory::encrypt(password)); - } - - q.bindValue(QSL(":update_type"), int(auto_update_type)); - q.bindValue(QSL(":update_interval"), auto_update_interval); - q.bindValue(QSL(":type"), int(feed_format)); - q.bindValue(QSL(":id"), feed_id); - - bool suc = q.exec(); - - if (!suc) { - qWarningNN << LOGSEC_DB - << "There was error when editing feed: '" - << q.lastError().text() - << "'."; - } - - return suc; -} - -bool DatabaseQueries::editFeed(const QSqlDatabase& db, int feed_id, Feed::AutoUpdateType auto_update_type, - int auto_update_interval, bool is_protected, const QString& username, - const QString& password) { - QSqlQuery q(db); - - q.setForwardOnly(true); - q.prepare("UPDATE Feeds " - "SET update_type = :update_type, update_interval = :update_interval, protected = :protected, username = :username, password = :password " - "WHERE id = :id;"); - q.bindValue(QSL(":update_type"), int(auto_update_type)); - q.bindValue(QSL(":update_interval"), auto_update_interval); - q.bindValue(QSL(":id"), feed_id); - q.bindValue(QSL(":protected"), is_protected ? 1 : 0); - q.bindValue(QSL(":username"), username); - - if (password.isEmpty()) { - q.bindValue(QSL(":password"), password); - } - else { - q.bindValue(QSL(":password"), TextFactory::encrypt(password)); - } - - return q.exec(); -} - MessageFilter* DatabaseQueries::addMessageFilter(const QSqlDatabase& db, const QString& title, const QString& script) { if (!db.driver()->hasFeature(QSqlDriver::DriverFeature::LastInsertId)) { diff --git a/src/librssguard/miscellaneous/databasequeries.h b/src/librssguard/miscellaneous/databasequeries.h index dc2ef2279..9c8a99851 100644 --- a/src/librssguard/miscellaneous/databasequeries.h +++ b/src/librssguard/miscellaneous/databasequeries.h @@ -112,10 +112,6 @@ 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 bool editFeed(const QSqlDatabase& db, int feed_id, - Feed::AutoUpdateType auto_update_type, int auto_update_interval, - bool is_protected, const QString& username, - const QString& password); template static Assignment getCategories(const QSqlDatabase& db, int account_id, bool* ok = nullptr); @@ -136,27 +132,16 @@ 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 addStandardCategory(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 editStandardCategory(const QSqlDatabase& db, int parent_id, int category_id, - const QString& title, const QString& description, const QIcon& icon); - static int addStandardFeed(const QSqlDatabase& db, int parent_id, int account_id, const QString& title, - const QString& description, const QDateTime& creation_date, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, - Feed::AutoUpdateType auto_update_type, int auto_update_interval, - StandardFeed::SourceType source_type, const QString& post_process_script, - StandardFeed::Type feed_format, bool* ok = nullptr); - static bool editStandardFeed(const QSqlDatabase& db, int parent_id, int feed_id, const QString& title, - const QString& description, const QIcon& icon, - const QString& encoding, const QString& url, bool is_protected, - const QString& username, const QString& password, Feed::AutoUpdateType auto_update_type, - int auto_update_interval, StandardFeed::SourceType source_type, - const QString& post_process_script, StandardFeed::Type feed_format); + 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 static void fillFeedData(T* feed, const QSqlRecord& sql_record); diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 6eddd5f4c..f5d964167 100755 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -22,11 +22,6 @@ Feed::Feed(RootItem* parent) : RootItem(parent), m_source(QString()), m_status(Status::Normal), m_autoUpdateType(AutoUpdateType::DefaultAutoUpdate), m_autoUpdateInitialInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_autoUpdateRemainingInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_messageFilters(QList>()) { - - m_passwordProtected = false; - m_username = QString(); - m_password = QString(); - setKind(RootItem::Kind::Feed); } @@ -46,16 +41,6 @@ Feed::Feed(const QSqlRecord& record) : Feed(nullptr) { setAutoUpdateType(static_cast(record.value(FDS_DB_UPDATE_TYPE_INDEX).toInt())); setAutoUpdateInitialInterval(record.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt()); - 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())); - } - qDebugNN << LOGSEC_CORE << "Custom ID of feed when loading from DB is" << QUOTE_W_SPACE_DOT(customId()); @@ -72,10 +57,6 @@ Feed::Feed(const Feed& other) : RootItem(other) { setAutoUpdateInitialInterval(other.autoUpdateInitialInterval()); setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval()); setMessageFilters(other.messageFilters()); - - setPasswordProtected(other.passwordProtected()); - setUsername(other.username()); - setPassword(other.password()); } Feed::~Feed() = default; @@ -86,30 +67,6 @@ QList Feed::undeletedMessages() const { return DatabaseQueries::getUndeletedMessagesForFeed(database, customId(), getParentServiceRoot()->accountId()); } -bool Feed::passwordProtected() const { - return m_passwordProtected; -} - -void Feed::setPasswordProtected(bool passwordProtected) { - m_passwordProtected = passwordProtected; -} - -QString Feed::username() const { - return m_username; -} - -void Feed::setUsername(const QString& username) { - m_username = username; -} - -QString Feed::password() const { - return m_password; -} - -void Feed::setPassword(const QString& password) { - m_password = password; -} - QVariant Feed::data(int column, int role) const { switch (role) { case Qt::ForegroundRole: @@ -171,30 +128,10 @@ bool Feed::canBeEdited() const { bool Feed::editViaGui() { QScopedPointer form_pointer(new FormFeedDetails(getParentServiceRoot(), qApp->mainFormWidget())); - form_pointer->editFeed(this); + form_pointer->addEditFeed(this); return false; } -bool Feed::editItself(Feed* new_feed_data) { - QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - - if (DatabaseQueries::editFeed(database, id(), new_feed_data->autoUpdateType(), - new_feed_data->autoUpdateInitialInterval(), - new_feed_data->passwordProtected(), - new_feed_data->username(), - new_feed_data->password())) { - setPasswordProtected(new_feed_data->passwordProtected()); - setUsername(new_feed_data->username()); - setPassword(new_feed_data->password()); - setAutoUpdateType(new_feed_data->autoUpdateType()); - setAutoUpdateInitialInterval(new_feed_data->autoUpdateInitialInterval()); - return true; - } - else { - return false; - } -} - void Feed::setAutoUpdateInitialInterval(int auto_update_interval) { // If new initial auto-update interval is set, then // we should reset time that remains to the next auto-update. diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index 7da038361..b3ee370d5 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -58,8 +58,6 @@ class Feed : public RootItem { bool canBeEdited() const; bool editViaGui(); - bool editItself(Feed* new_feed_data); - QVariant data(int column, int role) const; int autoUpdateInitialInterval() const; @@ -77,15 +75,6 @@ class Feed : public RootItem { QString source() const; void setSource(const QString& source); - bool passwordProtected() const; - void setPasswordProtected(bool passwordProtected); - - QString username() const; - void setUsername(const QString& username); - - QString password() const; - void setPassword(const QString& password); - void appendMessageFilter(MessageFilter* filter); QList> messageFilters() const; void setMessageFilters(const QList>& messageFilters); @@ -109,9 +98,6 @@ class Feed : public RootItem { int m_totalCount{}; int m_unreadCount{}; QList> m_messageFilters; - bool m_passwordProtected{}; - QString m_username; - QString m_password; }; Q_DECLARE_METATYPE(Feed::AutoUpdateType) diff --git a/src/librssguard/services/abstract/gui/formaccountdetails.cpp b/src/librssguard/services/abstract/gui/formaccountdetails.cpp index b6a07c89a..323c75ca9 100644 --- a/src/librssguard/services/abstract/gui/formaccountdetails.cpp +++ b/src/librssguard/services/abstract/gui/formaccountdetails.cpp @@ -19,8 +19,6 @@ FormAccountDetails::FormAccountDetails(const QIcon& icon, QWidget* parent) } void FormAccountDetails::apply() { - QSqlDatabase database = qApp->database()->connection(QSL("FormAccountDetails")); - m_account->setNetworkProxy(m_proxyDetails->proxy()); } diff --git a/src/librssguard/services/abstract/gui/formaccountdetails.h b/src/librssguard/services/abstract/gui/formaccountdetails.h index 054e806ca..d9c543bff 100644 --- a/src/librssguard/services/abstract/gui/formaccountdetails.h +++ b/src/librssguard/services/abstract/gui/formaccountdetails.h @@ -29,8 +29,8 @@ class FormAccountDetails : public QDialog { protected slots: // Applies changes. - // NOTE: This must be reimplemented in subclasses. Also, every - // subclass must call applyInternal() method as first statement. + // NOTE: This must be reimplemented in subclasses. Also this base + // implementation must be called first. virtual void apply(); protected: diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.cpp b/src/librssguard/services/abstract/gui/formfeeddetails.cpp index 64f54f797..dfcd2e033 100644 --- a/src/librssguard/services/abstract/gui/formfeeddetails.cpp +++ b/src/librssguard/services/abstract/gui/formfeeddetails.cpp @@ -8,6 +8,7 @@ #include "gui/guiutilities.h" #include "gui/messagebox.h" #include "gui/systemtrayicon.h" +#include "miscellaneous/databasequeries.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/textfactory.h" #include "network-web/networkfactory.h" @@ -23,16 +24,11 @@ #include FormFeedDetails::FormFeedDetails(ServiceRoot* service_root, QWidget* parent) - : QDialog(parent), m_editableFeed(nullptr), m_serviceRoot(service_root) { + : QDialog(parent), m_feed(nullptr), m_serviceRoot(service_root) { initialize(); createConnections(); } -int FormFeedDetails::editFeed(Feed* input_feed) { - setEditableFeed(input_feed); - return QDialog::exec(); -} - void FormFeedDetails::activateTab(int index) { m_ui->m_tabWidget->setCurrentIndex(index); } @@ -46,26 +42,10 @@ void FormFeedDetails::insertCustomTab(QWidget* custom_tab, const QString& title, } void FormFeedDetails::apply() { - Feed new_feed; - - // Setup data for new_feed. - new_feed.setAutoUpdateType(static_cast(m_ui->m_cmbAutoUpdateType->itemData( - m_ui->m_cmbAutoUpdateType->currentIndex()).toInt())); - new_feed.setAutoUpdateInitialInterval(int(m_ui->m_spinAutoUpdateInterval->value())); - - if (m_editableFeed != nullptr) { - // Edit the feed. - bool edited = m_editableFeed->editItself(&new_feed); - - if (edited) { - accept(); - } - else { - qApp->showGuiMessage(tr("Cannot edit feed"), - tr("Feed was not edited due to error."), - QSystemTrayIcon::MessageIcon::Critical, this, true); - } - } + // Setup common data for the feed. + m_feed->setAutoUpdateType(static_cast(m_ui->m_cmbAutoUpdateType->itemData( + m_ui->m_cmbAutoUpdateType->currentIndex()).toInt())); + m_feed->setAutoUpdateInitialInterval(int(m_ui->m_spinAutoUpdateInterval->value())); } void FormFeedDetails::onAutoUpdateTypeChanged(int new_index) { @@ -88,13 +68,16 @@ void FormFeedDetails::createConnections() { &FormFeedDetails::onAutoUpdateTypeChanged); } -void FormFeedDetails::setEditableFeed(Feed* editable_feed) { - setWindowTitle(tr("Edit '%1'").arg(editable_feed->title())); +void FormFeedDetails::loadFeedData() { + if (m_creatingNew) { + setWindowTitle(tr("Add new feed")); + } + else { + setWindowTitle(tr("Edit '%1'").arg(m_feed->title())); + } - m_editableFeed = editable_feed; - - m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue((int) editable_feed->autoUpdateType()))); - m_ui->m_spinAutoUpdateInterval->setValue(editable_feed->autoUpdateInitialInterval()); + m_ui->m_cmbAutoUpdateType->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue(int(m_feed->autoUpdateType())))); + m_ui->m_spinAutoUpdateInterval->setValue(m_feed->autoUpdateInitialInterval()); } void FormFeedDetails::initialize() { diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.h b/src/librssguard/services/abstract/gui/formfeeddetails.h index 9fdcf105a..9f4da0bb1 100644 --- a/src/librssguard/services/abstract/gui/formfeeddetails.h +++ b/src/librssguard/services/abstract/gui/formfeeddetails.h @@ -23,8 +23,11 @@ class FormFeedDetails : public QDialog { explicit FormFeedDetails(ServiceRoot* service_root, QWidget* parent = nullptr); virtual ~FormFeedDetails() = default; - public slots: - int editFeed(Feed* input_feed); + template + T* addEditFeed(T* account_to_edit = nullptr); + + template + T* feed() const; protected slots: void activateTab(int index); @@ -41,7 +44,7 @@ class FormFeedDetails : public QDialog { // Sets the feed which will be edited. // NOTE: This must be reimplemented in subclasses. Also this // base implementation must be called first. - void virtual setEditableFeed(Feed* editable_feed); + virtual void loadFeedData(); private slots: void onAutoUpdateTypeChanged(int new_index); @@ -52,8 +55,36 @@ class FormFeedDetails : public QDialog { protected: QScopedPointer m_ui; - Feed* m_editableFeed; + Feed* m_feed; ServiceRoot* m_serviceRoot; + bool m_creatingNew; }; +template +inline T* FormFeedDetails::addEditFeed(T* feed_to_edit) { + m_creatingNew = feed_to_edit == nullptr; + + if (m_creatingNew) { + m_feed = new T(); + } + else { + m_feed = feed_to_edit; + } + + // Load custom logic for feed data loading. + loadFeedData(); + + if (exec() == QDialog::DialogCode::Accepted) { + return feed(); + } + else { + return nullptr; + } +} + +template +inline T* FormFeedDetails::feed() const { + return qobject_cast(m_feed); +} + #endif // FORMFEEDDETAILS_H diff --git a/src/librssguard/services/owncloud/owncloudfeed.cpp b/src/librssguard/services/owncloud/owncloudfeed.cpp index 7336f157a..af6e58bd7 100644 --- a/src/librssguard/services/owncloud/owncloudfeed.cpp +++ b/src/librssguard/services/owncloud/owncloudfeed.cpp @@ -20,7 +20,8 @@ bool OwnCloudFeed::canBeDeleted() const { } bool OwnCloudFeed::deleteViaGui() { - if (serviceRoot()->network()->deleteFeed(customId(), getParentServiceRoot()->networkProxy()) && removeItself()) { + if (serviceRoot()->network()->deleteFeed(customId(), getParentServiceRoot()->networkProxy()) && + removeItself()) { serviceRoot()->requestItemRemoval(this); return true; } diff --git a/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp b/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp index 17b88a4fa..5e4badd94 100644 --- a/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp +++ b/src/librssguard/services/standard/gui/formstandardfeeddetails.cpp @@ -3,6 +3,7 @@ #include "services/standard/gui/formstandardfeeddetails.h" #include "miscellaneous/application.h" +#include "miscellaneous/databasequeries.h" #include "miscellaneous/iconfactory.h" #include "network-web/networkfactory.h" #include "services/abstract/category.h" @@ -15,9 +16,10 @@ #include #include -FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot* service_root, QWidget* parent) +FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select, + const QString& url, QWidget* parent) : FormFeedDetails(service_root, parent), m_standardFeedDetails(new StandardFeedDetails(this)), - m_authDetails(new AuthenticationDetails(this)) { + m_authDetails(new AuthenticationDetails(this)), m_parentToSelect(parent_to_select), m_urlToProcess(url) { insertCustomTab(m_standardFeedDetails, tr("General"), 0); insertCustomTab(m_authDetails, tr("Network"), 2); activateTab(0); @@ -26,26 +28,6 @@ FormStandardFeedDetails::FormStandardFeedDetails(ServiceRoot* service_root, QWid connect(m_standardFeedDetails->m_actionFetchIcon, &QAction::triggered, this, &FormStandardFeedDetails::guessIconOnly); } -int FormStandardFeedDetails::addEditFeed(StandardFeed* input_feed, RootItem* parent_to_select, const QString& url) { - // Load categories. - m_standardFeedDetails->loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot); - - if (input_feed == nullptr) { - // User is adding new feed. - setWindowTitle(tr("Add new feed")); - - auto processed_url = qobject_cast(m_serviceRoot)->processFeedUrl(url); - - m_standardFeedDetails->prepareForNewFeed(parent_to_select, processed_url); - } - else { - setEditableFeed(input_feed); - } - - // Run the dialog. - return exec(); -} - void FormStandardFeedDetails::guessFeed() { m_standardFeedDetails->guessFeed(m_standardFeedDetails->sourceType(), m_standardFeedDetails->m_ui.m_txtSource->textEdit()->toPlainText(), @@ -63,69 +45,58 @@ void FormStandardFeedDetails::guessIconOnly() { } void FormStandardFeedDetails::apply() { + FormFeedDetails::apply(); + + auto* std_feed = feed(); RootItem* parent = static_cast(m_standardFeedDetails->m_ui.m_cmbParentCategory->itemData( m_standardFeedDetails->m_ui.m_cmbParentCategory->currentIndex()).value()); StandardFeed::Type type = static_cast(m_standardFeedDetails->m_ui.m_cmbType->itemData(m_standardFeedDetails->m_ui.m_cmbType->currentIndex()).value()); - auto* new_feed = new StandardFeed(); // Setup data for new_feed. - new_feed->setTitle(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit()->text()); - new_feed->setCreationDate(QDateTime::currentDateTime()); - new_feed->setDescription(m_standardFeedDetails->m_ui.m_txtDescription->lineEdit()->text()); - new_feed->setIcon(m_standardFeedDetails->m_ui.m_btnIcon->icon()); - new_feed->setEncoding(m_standardFeedDetails->m_ui.m_cmbEncoding->currentText()); - new_feed->setType(type); - new_feed->setSourceType(m_standardFeedDetails->sourceType()); - new_feed->setPostProcessScript(m_standardFeedDetails->m_ui.m_txtPostProcessScript->textEdit()->toPlainText()); - new_feed->setSource(m_standardFeedDetails->m_ui.m_txtSource->textEdit()->toPlainText()); - new_feed->setPasswordProtected(m_authDetails->m_gbAuthentication->isChecked()); - new_feed->setUsername(m_authDetails->m_txtUsername->lineEdit()->text()); - new_feed->setPassword(m_authDetails->m_txtPassword->lineEdit()->text()); - new_feed->setAutoUpdateType(static_cast(m_ui->m_cmbAutoUpdateType->itemData( - m_ui->m_cmbAutoUpdateType->currentIndex()).toInt())); - new_feed->setAutoUpdateInitialInterval(int(m_ui->m_spinAutoUpdateInterval->value())); + std_feed->setTitle(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit()->text()); + std_feed->setCreationDate(QDateTime::currentDateTime()); + std_feed->setDescription(m_standardFeedDetails->m_ui.m_txtDescription->lineEdit()->text()); + std_feed->setIcon(m_standardFeedDetails->m_ui.m_btnIcon->icon()); - if (m_editableFeed == nullptr) { - // Add the feed. - if (new_feed->addItself(parent)) { - m_serviceRoot->requestItemReassignment(new_feed, parent); - accept(); - } - else { - delete new_feed; - qApp->showGuiMessage(tr("Cannot add feed"), - tr("Feed was not added due to error."), - QSystemTrayIcon::MessageIcon::Critical, this, true); - } + std_feed->setSource(m_standardFeedDetails->m_ui.m_txtSource->textEdit()->toPlainText()); + + std_feed->setEncoding(m_standardFeedDetails->m_ui.m_cmbEncoding->currentText()); + std_feed->setType(type); + std_feed->setSourceType(m_standardFeedDetails->sourceType()); + std_feed->setPostProcessScript(m_standardFeedDetails->m_ui.m_txtPostProcessScript->textEdit()->toPlainText()); + std_feed->setPasswordProtected(m_authDetails->m_gbAuthentication->isChecked()); + std_feed->setUsername(m_authDetails->m_txtUsername->lineEdit()->text()); + std_feed->setPassword(m_authDetails->m_txtPassword->lineEdit()->text()); + + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); + + DatabaseQueries::createOverwriteFeed(database, std_feed, m_serviceRoot->accountId(), parent->id()); + m_serviceRoot->requestItemReassignment(m_feed, parent); + + accept(); +} + +void FormStandardFeedDetails::loadFeedData() { + FormFeedDetails::loadFeedData(); + + auto* std_feed = feed(); + + // Load categories. + m_standardFeedDetails->loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot); + + m_authDetails->m_gbAuthentication->setChecked(std_feed->passwordProtected()); + m_authDetails->m_txtUsername->lineEdit()->setText(std_feed->username()); + m_authDetails->m_txtPassword->lineEdit()->setText(std_feed->password()); + + if (m_creatingNew) { + auto processed_url = qobject_cast(m_serviceRoot)->processFeedUrl(m_urlToProcess); + + m_standardFeedDetails->prepareForNewFeed(m_parentToSelect, processed_url); } else { - new_feed->setParent(parent); - - // Edit the feed. - bool edited = qobject_cast(m_editableFeed)->editItself(new_feed); - - if (edited) { - m_serviceRoot->requestItemReassignment(m_editableFeed, new_feed->parent()); - accept(); - } - else { - qApp->showGuiMessage(tr("Cannot edit feed"), - tr("Feed was not edited due to error."), - QSystemTrayIcon::MessageIcon::Critical, this, true); - } - - delete new_feed; + m_standardFeedDetails->setExistingFeed(std_feed); } } - -void FormStandardFeedDetails::setEditableFeed(Feed* editable_feed) { - FormFeedDetails::setEditableFeed(editable_feed); - - m_standardFeedDetails->setExistingFeed(qobject_cast(editable_feed)); - m_authDetails->m_gbAuthentication->setChecked(editable_feed->passwordProtected()); - m_authDetails->m_txtUsername->lineEdit()->setText(editable_feed->username()); - m_authDetails->m_txtPassword->lineEdit()->setText(editable_feed->password()); -} diff --git a/src/librssguard/services/standard/gui/formstandardfeeddetails.h b/src/librssguard/services/standard/gui/formstandardfeeddetails.h index a5b43e1ae..a7390987d 100644 --- a/src/librssguard/services/standard/gui/formstandardfeeddetails.h +++ b/src/librssguard/services/standard/gui/formstandardfeeddetails.h @@ -13,10 +13,8 @@ class FormStandardFeedDetails : public FormFeedDetails { Q_OBJECT public: - explicit FormStandardFeedDetails(ServiceRoot* service_root, QWidget* parent = nullptr); - - public slots: - int addEditFeed(StandardFeed* input_feed, RootItem* parent_to_select, const QString& url = QString()); + explicit FormStandardFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select = nullptr, + const QString& url = QString(), QWidget* parent = nullptr); private slots: void guessFeed(); @@ -25,11 +23,13 @@ class FormStandardFeedDetails : public FormFeedDetails { virtual void apply(); private: - virtual void setEditableFeed(Feed* editable_feed); + virtual void loadFeedData(); private: StandardFeedDetails* m_standardFeedDetails; AuthenticationDetails* m_authDetails; + RootItem* m_parentToSelect; + QString m_urlToProcess; }; #endif // FORMSSFEEDDETAILS_H diff --git a/src/librssguard/services/standard/gui/standardfeeddetails.cpp b/src/librssguard/services/standard/gui/standardfeeddetails.cpp index 9b0636684..541c308c4 100755 --- a/src/librssguard/services/standard/gui/standardfeeddetails.cpp +++ b/src/librssguard/services/standard/gui/standardfeeddetails.cpp @@ -311,6 +311,9 @@ void StandardFeedDetails::prepareForNewFeed(RootItem* parent_to_select, const QS m_ui.m_cmbParentCategory->setCurrentIndex(target_item); } } + else { + m_ui.m_cmbParentCategory->setCurrentIndex(0); + } } if (!url.isEmpty()) { diff --git a/src/librssguard/services/standard/standardcategory.cpp b/src/librssguard/services/standard/standardcategory.cpp index ca2e35ce6..a77a506bc 100644 --- a/src/librssguard/services/standard/standardcategory.cpp +++ b/src/librssguard/services/standard/standardcategory.cpp @@ -97,7 +97,7 @@ 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::addStandardCategory(database, parent->id(), parent->getParentServiceRoot()->accountId(), + int new_id = DatabaseQueries::addCategory(database, parent->id(), parent->getParentServiceRoot()->accountId(), title(), description(), creationDate(), icon()); if (new_id <= 0) { @@ -115,7 +115,7 @@ bool StandardCategory::editItself(StandardCategory* new_category_data) { StandardCategory* original_category = this; RootItem* new_parent = new_category_data->parent(); - if (DatabaseQueries::editStandardCategory(database, new_parent->id(), original_category->id(), + 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. diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp index 233b34674..8c9627cee 100644 --- a/src/librssguard/services/standard/standardfeed.cpp +++ b/src/librssguard/services/standard/standardfeed.cpp @@ -41,6 +41,10 @@ StandardFeed::StandardFeed(RootItem* parent_item) m_type = Type::Rss0X; m_sourceType = SourceType::Url; m_encoding = m_postProcessScript = QString(); + + m_passwordProtected = false; + m_username = QString(); + m_password = QString(); } StandardFeed::StandardFeed(const StandardFeed& other) @@ -50,6 +54,9 @@ StandardFeed::StandardFeed(const StandardFeed& other) m_postProcessScript = other.postProcessScript(); m_sourceType = other.sourceType(); m_encoding = other.encoding(); + m_passwordProtected = other.passwordProtected(); + m_username = other.username(); + m_password = other.password(); } StandardFeed::~StandardFeed() { @@ -68,10 +75,6 @@ QString StandardFeed::additionalTooltip() const { StandardFeed::typeToString(type())); } -bool StandardFeed::canBeEdited() const { - return true; -} - bool StandardFeed::canBeDeleted() const { return true; } @@ -82,9 +85,11 @@ StandardServiceRoot* StandardFeed::serviceRoot() const { bool StandardFeed::editViaGui() { QScopedPointer form_pointer(new FormStandardFeedDetails(serviceRoot(), + nullptr, + {}, qApp->mainFormWidget())); - form_pointer->addEditFeed(this, this); + form_pointer->addEditFeed(this); return false; } @@ -98,6 +103,30 @@ bool StandardFeed::deleteViaGui() { } } +bool StandardFeed::passwordProtected() const { + return m_passwordProtected; +} + +void StandardFeed::setPasswordProtected(bool passwordProtected) { + m_passwordProtected = passwordProtected; +} + +QString StandardFeed::username() const { + return m_username; +} + +void StandardFeed::setUsername(const QString& username) { + m_username = username; +} + +QString StandardFeed::password() const { + return m_password; +} + +void StandardFeed::setPassword(const QString& password) { + m_password = password; +} + QVariantHash StandardFeed::customDatabaseData() const { QVariantHash data; @@ -169,19 +198,18 @@ void StandardFeed::fetchMetadataForItself() { getParentServiceRoot()->networkProxy()); if (metadata != nullptr && result) { - // Some properties are not updated when new metadata are fetched. - metadata->setParent(parent()); - metadata->setSource(source()); - metadata->setPasswordProtected(passwordProtected()); - metadata->setUsername(username()); - metadata->setPassword(password()); - metadata->setAutoUpdateType(autoUpdateType()); - metadata->setAutoUpdateInitialInterval(autoUpdateInitialInterval()); - metadata->setPostProcessScript(postProcessScript()); - metadata->setSourceType(sourceType()); - editItself(metadata); + // Copy metadata to our object. + setTitle(metadata->title()); + setDescription(metadata->description()); + setType(metadata->type()); + setEncoding(metadata->encoding()); + setIcon(metadata->icon()); delete metadata; + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); + + DatabaseQueries::createOverwriteFeed(database, this, getParentServiceRoot()->accountId(), parent()->id()); + // Notify the model about fact, that it needs to reload new information about // this item, particularly the icon. serviceRoot()->itemChanged(QList() << this); @@ -476,19 +504,11 @@ Qt::ItemFlags StandardFeed::additionalFlags() const { } bool StandardFeed::performDragDropChange(RootItem* target_item) { - auto* feed_new = new StandardFeed(*this); + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - feed_new->setParent(target_item); - - if (editItself(feed_new)) { - serviceRoot()->requestItemReassignment(this, target_item); - delete feed_new; - return true; - } - else { - delete feed_new; - return false; - } + DatabaseQueries::createOverwriteFeed(database, this, getParentServiceRoot()->accountId(), target_item->id()); + serviceRoot()->requestItemReassignment(this, target_item); + return true; } bool StandardFeed::removeItself() { @@ -497,66 +517,6 @@ bool StandardFeed::removeItself() { return DatabaseQueries::deleteFeed(database, customId().toInt(), getParentServiceRoot()->accountId()); } -bool StandardFeed::addItself(RootItem* parent) { - // Now, add feed to persistent storage. - QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - bool ok; - int new_id = DatabaseQueries::addStandardFeed(database, parent->id(), parent->getParentServiceRoot()->accountId(), - title(), description(), creationDate(), icon(), encoding(), source(), - passwordProtected(), username(), password(), autoUpdateType(), - autoUpdateInitialInterval(), sourceType(), postProcessScript(), - type(), &ok); - - if (!ok) { - // Query failed. - return false; - } - else { - // New feed was added, fetch is primary id from the database. - setId(new_id); - setCustomId(QString::number(new_id)); - return true; - } -} - -bool StandardFeed::editItself(StandardFeed* new_feed_data) { - QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - StandardFeed* original_feed = this; - RootItem* new_parent = new_feed_data->parent(); - - if (!DatabaseQueries::editStandardFeed(database, new_parent->id(), original_feed->id(), new_feed_data->title(), - new_feed_data->description(), new_feed_data->icon(), - new_feed_data->encoding(), new_feed_data->source(), new_feed_data->passwordProtected(), - new_feed_data->username(), new_feed_data->password(), - new_feed_data->autoUpdateType(), new_feed_data->autoUpdateInitialInterval(), - new_feed_data->sourceType(), new_feed_data->postProcessScript(), - new_feed_data->type())) { - // Persistent storage update failed, no way to continue now. - qWarningNN << LOGSEC_CORE - << "Self-editing of standard feed failed."; - return false; - } - - // Setup new model data for the original item. - original_feed->setTitle(new_feed_data->title()); - original_feed->setDescription(new_feed_data->description()); - original_feed->setIcon(new_feed_data->icon()); - original_feed->setEncoding(new_feed_data->encoding()); - original_feed->setDescription(new_feed_data->description()); - original_feed->setSource(new_feed_data->source()); - original_feed->setPasswordProtected(new_feed_data->passwordProtected()); - original_feed->setUsername(new_feed_data->username()); - original_feed->setPassword(new_feed_data->password()); - original_feed->setAutoUpdateType(new_feed_data->autoUpdateType()); - original_feed->setAutoUpdateInitialInterval(new_feed_data->autoUpdateInitialInterval()); - original_feed->setType(new_feed_data->type()); - original_feed->setSourceType(new_feed_data->sourceType()); - original_feed->setPostProcessScript(new_feed_data->postProcessScript()); - - // Editing is done. - return true; -} - StandardFeed::Type StandardFeed::type() const { return m_type; } @@ -786,6 +746,16 @@ StandardFeed::StandardFeed(const QSqlRecord& record) : Feed(record) { 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(record.value(FDS_DB_TYPE_INDEX).toInt()); switch (type) { diff --git a/src/librssguard/services/standard/standardfeed.h b/src/librssguard/services/standard/standardfeed.h index b7c5ab4fb..b478372c8 100644 --- a/src/librssguard/services/standard/standardfeed.h +++ b/src/librssguard/services/standard/standardfeed.h @@ -47,11 +47,10 @@ class StandardFeed : public Feed { QString additionalTooltip() const; - bool canBeEdited() const; bool canBeDeleted() const; + bool deleteViaGui(); bool editViaGui(); - bool deleteViaGui(); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); @@ -60,8 +59,6 @@ class StandardFeed : public Feed { Qt::ItemFlags additionalFlags() const; bool performDragDropChange(RootItem* target_item); - bool addItself(RootItem* parent); - bool editItself(StandardFeed* new_feed_data); bool removeItself(); // Other getters/setters. @@ -77,6 +74,15 @@ class StandardFeed : public Feed { QString postProcessScript() const; void setPostProcessScript(const QString& post_process_script); + bool passwordProtected() const; + void setPasswordProtected(bool passwordProtected); + + QString username() const; + void setUsername(const QString& username); + + QString password() const; + void setPassword(const QString& password); + QNetworkReply::NetworkError networkError() const; QList obtainNewMessages(bool* error_during_obtaining); @@ -113,9 +119,11 @@ class StandardFeed : public Feed { SourceType m_sourceType; Type m_type; QString m_postProcessScript; - QNetworkReply::NetworkError m_networkError; QString m_encoding; + bool m_passwordProtected{}; + QString m_username; + QString m_password; }; Q_DECLARE_METATYPE(StandardFeed::SourceType) diff --git a/src/librssguard/services/standard/standardserviceroot.cpp b/src/librssguard/services/standard/standardserviceroot.cpp index ca15b7cd5..64e5b3e9e 100644 --- a/src/librssguard/services/standard/standardserviceroot.cpp +++ b/src/librssguard/services/standard/standardserviceroot.cpp @@ -120,9 +120,11 @@ void StandardServiceRoot::addNewFeed(RootItem* selected_item, const QString& url } QScopedPointer form_pointer(new FormStandardFeedDetails(this, + selected_item, + url, qApp->mainFormWidget())); - form_pointer->addEditFeed(nullptr, selected_item, url); + form_pointer->addEditFeed(); qApp->feedUpdateLock()->unlock(); } @@ -239,15 +241,13 @@ bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel* model, else if (source_item->kind() == RootItem::Kind::Feed) { auto* source_feed = dynamic_cast(source_item); auto* new_feed = new StandardFeed(*source_feed); + QSqlDatabase database = qApp->database()->connection(metaObject()->className()); - // Append this feed and end this iteration. - if (new_feed->addItself(target_parent)) { - requestItemReassignment(new_feed, target_parent); - } - else { - delete new_feed; - some_feed_category_error = true; - } + DatabaseQueries::createOverwriteFeed(database, + new_feed, + target_root_node->getParentServiceRoot()->accountId(), + target_parent->id()); + requestItemReassignment(new_feed, target_parent); } } } diff --git a/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp b/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp index 805639cfe..a287f04eb 100755 --- a/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp +++ b/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.cpp @@ -15,34 +15,14 @@ #include #include -FormTtRssFeedDetails::FormTtRssFeedDetails(ServiceRoot* service_root, QWidget* parent) +FormTtRssFeedDetails::FormTtRssFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select, + const QString& url, QWidget* parent) : FormFeedDetails(service_root, parent), m_feedDetails(new TtRssFeedDetails(this)), - m_authDetails(new AuthenticationDetails(this)) {} - -int FormTtRssFeedDetails::addFeed(RootItem* parent_to_select, const QString& url) { - clearTabs(); - insertCustomTab(m_feedDetails, tr("General"), 0); - insertCustomTab(m_authDetails, tr("Network"), 1); - activateTab(0); - - setWindowTitle(tr("Add new feed")); - m_feedDetails->loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot, parent_to_select); - - if (!url.isEmpty()) { - m_feedDetails->ui.m_txtUrl->lineEdit()->setText(url); - } - else if (Application::clipboard()->mimeData()->hasText()) { - m_feedDetails->ui.m_txtUrl->lineEdit()->setText(Application::clipboard()->text()); - } - - m_feedDetails->ui.m_txtUrl->lineEdit()->selectAll(); - m_feedDetails->ui.m_txtUrl->setFocus(); - - return exec(); -} + m_authDetails(new AuthenticationDetails(this)), m_parentToSelect(parent_to_select), + m_urlToProcess(url) {} void FormTtRssFeedDetails::apply() { - if (m_editableFeed != nullptr) { + if (!m_creatingNew) { // NOTE: We can only edit base properties, therefore // base method is fine. FormFeedDetails::apply(); @@ -78,3 +58,25 @@ void FormTtRssFeedDetails::apply() { } } } + +void FormTtRssFeedDetails::loadFeedData() { + FormFeedDetails::loadFeedData(); + + if (m_creatingNew) { + insertCustomTab(m_feedDetails, tr("General"), 0); + insertCustomTab(m_authDetails, tr("Network"), 1); + activateTab(0); + + m_feedDetails->loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot, m_parentToSelect); + + if (!m_urlToProcess.isEmpty()) { + m_feedDetails->ui.m_txtUrl->lineEdit()->setText(m_urlToProcess); + } + else if (Application::clipboard()->mimeData()->hasText()) { + m_feedDetails->ui.m_txtUrl->lineEdit()->setText(Application::clipboard()->text()); + } + + m_feedDetails->ui.m_txtUrl->lineEdit()->selectAll(); + m_feedDetails->ui.m_txtUrl->setFocus(); + } +} diff --git a/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.h b/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.h index 899b7abf8..00273a4ed 100755 --- a/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.h +++ b/src/librssguard/services/tt-rss/gui/formttrssfeeddetails.h @@ -11,17 +11,20 @@ class AuthenticationDetails; class FormTtRssFeedDetails : public FormFeedDetails { public: - explicit FormTtRssFeedDetails(ServiceRoot* service_root, QWidget* parent = nullptr); - - public slots: - int addFeed(RootItem* parent_to_select, const QString& url = QString()); + explicit FormTtRssFeedDetails(ServiceRoot* service_root, RootItem* parent_to_select = nullptr, + const QString& url = QString(), QWidget* parent = nullptr); protected slots: virtual void apply(); + private: + virtual void loadFeedData(); + private: TtRssFeedDetails* m_feedDetails; AuthenticationDetails* m_authDetails; + RootItem* m_parentToSelect; + QString m_urlToProcess; }; #endif // FORMTTRSSFEEDDETAILS_H diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index 9a7adf69e..9fd444697 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -93,9 +93,9 @@ void TtRssServiceRoot::addNewFeed(RootItem* selected_item, const QString& url) { return; } - QScopedPointer form_pointer(new FormTtRssFeedDetails(this, qApp->mainFormWidget())); + QScopedPointer form_pointer(new FormTtRssFeedDetails(this, selected_item, url, qApp->mainFormWidget())); - form_pointer->addFeed(selected_item, url); + form_pointer->addEditFeed(); qApp->feedUpdateLock()->unlock(); }