diff --git a/resources/sql.qrc b/resources/sql.qrc
index 77e8cb8db..0187a0294 100644
--- a/resources/sql.qrc
+++ b/resources/sql.qrc
@@ -7,6 +7,7 @@
sql/db_update_mysql_4_5.sql
sql/db_update_mysql_5_6.sql
sql/db_update_mysql_6_7.sql
+ sql/db_update_mysql_7_8.sql
sql/db_init_sqlite.sql
sql/db_update_sqlite_1_2.sql
@@ -15,5 +16,6 @@
sql/db_update_sqlite_4_5.sql
sql/db_update_sqlite_5_6.sql
sql/db_update_sqlite_6_7.sql
+ sql/db_update_sqlite_7_8.sql
\ No newline at end of file
diff --git a/resources/sql/db_init_sqlite.sql b/resources/sql/db_init_sqlite.sql
index c4ce4dbd5..1329c8bfa 100644
--- a/resources/sql/db_init_sqlite.sql
+++ b/resources/sql/db_init_sqlite.sql
@@ -44,8 +44,15 @@ CREATE TABLE Feeds (
is_off INTEGER NOT NULL DEFAULT 0 CHECK (is_off >= 0 AND is_off <= 1),
is_quiet INTEGER NOT NULL DEFAULT 0 CHECK (is_quiet >= 0 AND is_quiet <= 1),
is_rtl INTEGER NOT NULL DEFAULT 0 CHECK (is_rtl >= 0 AND is_rtl <= 1),
+
add_any_datetime_articles INTEGER NOT NULL DEFAULT 0 CHECK (add_any_datetime_articles >= 0 AND add_any_datetime_articles <= 1),
datetime_to_avoid BIGINT NOT NULL DEFAULT 0 CHECK (datetime_to_avoid >= 0),
+
+ keep_article_count INTEGER NOT NULL DEFAULT 0 CHECK (keep_article_count >= 0),
+ keep_unread_articles INTEGER NOT NULL DEFAULT 1 CHECK (keep_unread_articles >= 0 AND keep_unread_articles <= 1),
+ keep_starred_articles INTEGER NOT NULL DEFAULT 1 CHECK (keep_starred_articles >= 0 AND keep_starred_articles <= 1),
+ recycle_articles INTEGER NOT NULL DEFAULT 0 CHECK (recycle_articles >= 0 AND recycle_articles <= 1),
+
open_articles INTEGER NOT NULL DEFAULT 0 CHECK (open_articles >= 0 AND open_articles <= 1),
account_id INTEGER NOT NULL,
custom_id TEXT NOT NULL CHECK (custom_id != ''), /* Custom ID cannot be empty, it must contain either service-specific ID, or Feeds/id. */
diff --git a/resources/sql/db_update_mysql_7_8.sql b/resources/sql/db_update_mysql_7_8.sql
new file mode 100644
index 000000000..180f4d887
--- /dev/null
+++ b/resources/sql/db_update_mysql_7_8.sql
@@ -0,0 +1,7 @@
+USE ##;
+-- !
+SET FOREIGN_KEY_CHECKS = 0;
+-- !
+!! db_update_sqlite_7_8.sql
+-- !
+SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
diff --git a/resources/sql/db_update_sqlite_7_8.sql b/resources/sql/db_update_sqlite_7_8.sql
new file mode 100644
index 000000000..b9f317b49
--- /dev/null
+++ b/resources/sql/db_update_sqlite_7_8.sql
@@ -0,0 +1,39 @@
+ALTER TABLE Feeds RENAME TO backup_Feeds;
+-- !
+CREATE TABLE Feeds (
+ id $$,
+ ordr INTEGER NOT NULL CHECK (ordr >= 0),
+ title TEXT NOT NULL CHECK (title != ''),
+ description TEXT,
+ date_created BIGINT,
+ icon ^^,
+ category INTEGER NOT NULL CHECK (category >= -1), /* Physical category ID, also root feeds contain -1 here. */
+ source TEXT,
+ update_type INTEGER NOT NULL CHECK (update_type >= 0),
+ update_interval INTEGER NOT NULL DEFAULT 900 CHECK (update_interval >= 1),
+ is_off INTEGER NOT NULL DEFAULT 0 CHECK (is_off >= 0 AND is_off <= 1),
+ is_quiet INTEGER NOT NULL DEFAULT 0 CHECK (is_quiet >= 0 AND is_quiet <= 1),
+ is_rtl INTEGER NOT NULL DEFAULT 0 CHECK (is_rtl >= 0 AND is_rtl <= 1),
+
+ add_any_datetime_articles INTEGER NOT NULL DEFAULT 0 CHECK (add_any_datetime_articles >= 0 AND add_any_datetime_articles <= 1),
+ datetime_to_avoid BIGINT NOT NULL DEFAULT 0 CHECK (datetime_to_avoid >= 0),
+
+ keep_article_count INTEGER NOT NULL DEFAULT 0 CHECK (keep_article_count >= 0),
+ keep_unread_articles INTEGER NOT NULL DEFAULT 1 CHECK (keep_unread_articles >= 0 AND keep_unread_articles <= 1),
+ keep_starred_articles INTEGER NOT NULL DEFAULT 1 CHECK (keep_starred_articles >= 0 AND keep_starred_articles <= 1),
+ recycle_articles INTEGER NOT NULL DEFAULT 0 CHECK (recycle_articles >= 0 AND recycle_articles <= 1),
+
+ open_articles INTEGER NOT NULL DEFAULT 0 CHECK (open_articles >= 0 AND open_articles <= 1),
+ account_id INTEGER NOT NULL,
+ 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
+);
+-- !
+INSERT INTO Feeds (id, ordr, title, description, date_created, icon, category, source, update_type, update_interval, is_off, is_quiet, is_rtl, add_any_datetime_articles, datetime_to_avoid, open_articles, account_id, custom_id, custom_data)
+SELECT id, ordr, title, description, date_created, icon, category, source, update_type, update_interval, is_off, is_quiet, is_rtl, add_any_datetime_articles, datetime_to_avoid, open_articles, account_id, custom_id, custom_data
+FROM backup_Feeds;
+-- !
+DROP TABLE backup_Feeds;
\ No newline at end of file
diff --git a/src/librssguard/definitions/definitions.h b/src/librssguard/definitions/definitions.h
index 731fa3911..b90416209 100644
--- a/src/librssguard/definitions/definitions.h
+++ b/src/librssguard/definitions/definitions.h
@@ -226,7 +226,7 @@
#define APP_DB_SQLITE_FILE "database.db"
// Keep this in sync with schema versions declared in SQL initialization code.
-#define APP_DB_SCHEMA_VERSION "7"
+#define APP_DB_SCHEMA_VERSION "8"
#define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql"
#define APP_DB_COMMENT_SPLIT "-- !\n"
#define APP_DB_INCLUDE_PLACEHOLDER "!!"
@@ -311,10 +311,14 @@
#define FDS_DB_IS_RTL_INDEX 12
#define FDS_DB_ADD_ANY_DATETIME_ARTICLES_INDEX 13
#define FDS_DB_DATETIME_TO_AVOID_INDEX 14
-#define FDS_DB_OPEN_ARTICLES_INDEX 15
-#define FDS_DB_ACCOUNT_ID_INDEX 16
-#define FDS_DB_CUSTOM_ID_INDEX 17
-#define FDS_DB_CUSTOM_DATA_INDEX 18
+#define FDS_DB_KEEP_ARTICLES_COUNT 15
+#define FDS_DB_KEEP_UNREAD_ARTICLES 16
+#define FDS_DB_KEEP_STARRED_ARTICLES 17
+#define RECYCLE_ARTICLE_DONT_PURGE 18
+#define FDS_DB_OPEN_ARTICLES_INDEX 19
+#define FDS_DB_ACCOUNT_ID_INDEX 20
+#define FDS_DB_CUSTOM_ID_INDEX 21
+#define FDS_DB_CUSTOM_DATA_INDEX 22
// Indexes of columns for feed models.
#define FDS_MODEL_TITLE_INDEX 0
diff --git a/src/librssguard/gui/reusable/articleamountcontrol.cpp b/src/librssguard/gui/reusable/articleamountcontrol.cpp
index 43034fd5d..a83603e43 100644
--- a/src/librssguard/gui/reusable/articleamountcontrol.cpp
+++ b/src/librssguard/gui/reusable/articleamountcontrol.cpp
@@ -26,6 +26,10 @@ ArticleAmountControl::ArticleAmountControl(QWidget* parent) : QWidget(parent) {
m_ui.m_dtDateTimeToAvoid
->setDisplayFormat(qApp->localization()->loadedLocale().dateTimeFormat(QLocale::FormatType::ShortFormat));
+ connect(m_ui.m_cbAddAnyDateArticles, &QCheckBox::toggled, this, [this](bool checked) {
+ m_ui.m_gbAvoidOldArticles->setEnabled(!checked);
+ });
+
// Ignoring articles.
connect(m_ui.m_cbAddAnyDateArticles, &QCheckBox::toggled, this, &ArticleAmountControl::changed);
connect(m_ui.m_gbAvoidOldArticles, &QGroupBox::toggled, this, &ArticleAmountControl::changed);
@@ -58,15 +62,13 @@ void ArticleAmountControl::setForAppWideFeatures(bool app_wide, bool batch_edit)
if (batch_edit) {
// We hook batch selectors.
- /*
- m_ui.m_mcbAutoDownloading->addActionWidget(m_ui.m_wdgAutoUpdate);
m_ui.m_mcbAddAnyDateArticles->addActionWidget(m_ui.m_cbAddAnyDateArticles);
- m_ui.m_mcbOpenArticlesAutomatically->addActionWidget(m_ui.m_cbOpenArticlesAutomatically);
- m_ui.m_mcbAvoidOldArticles->addActionWidget(m_ui.m_gbAvoidOldArticles);
- m_ui.m_mcbDisableFeed->addActionWidget(m_ui.m_cbDisableFeed);
- m_ui.m_mcbSuppressFeed->addActionWidget(m_ui.m_cbSuppressFeed);
- m_ui.m_mcbFeedRtl->addActionWidget(m_ui.m_cbFeedRTL);
- */
+ m_ui.m_mcbAvoidOldArticles->addActionWidget(m_ui.m_wdgAvoidOldArticles);
+
+ m_ui.m_mcbArticleCount->addActionWidget(m_ui.m_spinArticleCount);
+ m_ui.m_mcbMoveToBinNoPurge->addActionWidget(m_ui.m_cbMoveToBinNoPurge);
+ m_ui.m_mcbNoRemoveImportant->addActionWidget(m_ui.m_cbNoRemoveImportant);
+ m_ui.m_mcbNoRemoveUnread->addActionWidget(m_ui.m_cbNoRemoveUnread);
}
else {
// We hide batch selectors.
@@ -119,6 +121,33 @@ ArticleAmountControl::Setup ArticleAmountControl::save() const {
return setup;
}
+bool isChangeAllowed(MultiFeedEditCheckBox* mcb) {
+ return mcb->isChecked();
+}
+
+void ArticleAmountControl::saveFeed(Feed* fd) const {
+ if (isChangeAllowed(m_ui.m_mcbAddAnyDateArticles)) {
+ fd->setAddAnyDatetimeArticles(m_ui.m_cbAddAnyDateArticles->isChecked());
+ }
+
+ if (isChangeAllowed(m_ui.m_mcbAvoidOldArticles)) {
+ if (m_ui.m_gbAvoidOldArticles->isChecked()) {
+ if (m_ui.m_rbAvoidAbsolute->isChecked()) {
+ fd->setDatetimeToAvoid(m_ui.m_dtDateTimeToAvoid->dateTime());
+ fd->setHoursToAvoid(0);
+ }
+ else {
+ fd->setDatetimeToAvoid({});
+ fd->setHoursToAvoid(m_ui.m_spinHoursAvoid->value());
+ }
+ }
+ else {
+ fd->setDatetimeToAvoid({});
+ fd->setHoursToAvoid(0);
+ }
+ }
+}
+
void ArticleAmountControl::updateArticleCountSuffix(int count) {
m_ui.m_spinArticleCount->setSuffix(QSL(" ") + tr("newest article(s)", nullptr, count));
}
diff --git a/src/librssguard/gui/reusable/articleamountcontrol.h b/src/librssguard/gui/reusable/articleamountcontrol.h
index 047b9150d..14bdc68ba 100644
--- a/src/librssguard/gui/reusable/articleamountcontrol.h
+++ b/src/librssguard/gui/reusable/articleamountcontrol.h
@@ -7,9 +7,13 @@
#include "ui_articleamountcontrol.h"
+class Feed;
+
class ArticleAmountControl : public QWidget {
Q_OBJECT
+ friend class FormFeedDetails;
+
public:
struct Setup {
// Ignoring articles.
@@ -32,6 +36,8 @@ class ArticleAmountControl : public QWidget {
void load(const Setup& setup);
Setup save() const;
+ void saveFeed(Feed* fd) const;
+
private slots:
void updateArticleCountSuffix(int count);
diff --git a/src/librssguard/gui/reusable/articleamountcontrol.ui b/src/librssguard/gui/reusable/articleamountcontrol.ui
index 334c4fa6a..f900794a0 100644
--- a/src/librssguard/gui/reusable/articleamountcontrol.ui
+++ b/src/librssguard/gui/reusable/articleamountcontrol.ui
@@ -29,7 +29,7 @@
-
- 0
+ 1
@@ -39,7 +39,7 @@
-
-
-
+
-
@@ -176,7 +176,7 @@
-
-
-
+
-
@@ -210,7 +210,7 @@
-
-
-
+
-
@@ -224,7 +224,7 @@
-
-
-
+
-
@@ -238,7 +238,7 @@
-
-
-
+
-
diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.cpp b/src/librssguard/services/abstract/gui/formfeeddetails.cpp
index f3429e641..be0072fd1 100644
--- a/src/librssguard/services/abstract/gui/formfeeddetails.cpp
+++ b/src/librssguard/services/abstract/gui/formfeeddetails.cpp
@@ -55,26 +55,7 @@ void FormFeedDetails::apply() {
fd->setIsRtl(m_ui.m_cbFeedRTL->isChecked());
}
- if (isChangeAllowed(m_ui.m_mcbAddAnyDateArticles)) {
- fd->setAddAnyDatetimeArticles(m_ui.m_cbAddAnyDateArticles->isChecked());
- }
-
- if (isChangeAllowed(m_ui.m_mcbAvoidOldArticles)) {
- if (m_ui.m_gbAvoidOldArticles->isChecked()) {
- if (m_ui.m_rbAvoidAbsolute->isChecked()) {
- fd->setDatetimeToAvoid(m_ui.m_dtDateTimeToAvoid->dateTime());
- fd->setHoursToAvoid(0);
- }
- else {
- fd->setDatetimeToAvoid({});
- fd->setHoursToAvoid(m_ui.m_spinHoursAvoid->value());
- }
- }
- else {
- fd->setDatetimeToAvoid({});
- fd->setHoursToAvoid(0);
- }
- }
+ m_ui.m_wdgArticleLimiting->saveFeed(fd);
if (isChangeAllowed(m_ui.m_mcbDisableFeed)) {
fd->setIsSwitchedOff(m_ui.m_cbDisableFeed->isChecked());
@@ -122,10 +103,6 @@ void FormFeedDetails::createConnections() {
static_cast(&QComboBox::currentIndexChanged),
this,
&FormFeedDetails::onAutoUpdateTypeChanged);
-
- connect(m_ui.m_cbAddAnyDateArticles, &QCheckBox::toggled, this, [this](bool checked) {
- m_ui.m_gbAvoidOldArticles->setEnabled(!checked);
- });
}
void FormFeedDetails::loadFeedData() {
@@ -134,9 +111,7 @@ void FormFeedDetails::loadFeedData() {
if (m_isBatchEdit) {
// We hook batch selectors.
m_ui.m_mcbAutoDownloading->addActionWidget(m_ui.m_wdgAutoUpdate);
- m_ui.m_mcbAddAnyDateArticles->addActionWidget(m_ui.m_cbAddAnyDateArticles);
m_ui.m_mcbOpenArticlesAutomatically->addActionWidget(m_ui.m_cbOpenArticlesAutomatically);
- m_ui.m_mcbAvoidOldArticles->addActionWidget(m_ui.m_gbAvoidOldArticles);
m_ui.m_mcbDisableFeed->addActionWidget(m_ui.m_cbDisableFeed);
m_ui.m_mcbSuppressFeed->addActionWidget(m_ui.m_cbSuppressFeed);
m_ui.m_mcbFeedRtl->addActionWidget(m_ui.m_cbFeedRTL);
@@ -148,6 +123,8 @@ void FormFeedDetails::loadFeedData() {
}
}
+ m_ui.m_wdgArticleLimiting->setForAppWideFeatures(false, m_isBatchEdit);
+
if (m_creatingNew) {
GuiUtilities::applyDialogProperties(*this,
qApp->icons()->fromTheme(QSL("application-rss+xml")),
@@ -169,21 +146,23 @@ void FormFeedDetails::loadFeedData() {
m_ui.m_spinAutoUpdateInterval->setValue(fd->autoUpdateInterval());
m_ui.m_cbOpenArticlesAutomatically->setChecked(fd->openArticlesDirectly());
m_ui.m_cbFeedRTL->setChecked(fd->isRtl());
- m_ui.m_cbAddAnyDateArticles->setChecked(fd->addAnyDatetimeArticles());
- m_ui.m_gbAvoidOldArticles->setChecked((fd->datetimeToAvoid().isValid() &&
- fd->datetimeToAvoid().toMSecsSinceEpoch() > 0) ||
- fd->hoursToAvoid() > 0);
- m_ui.m_dtDateTimeToAvoid->setDateTime(fd->datetimeToAvoid());
- m_ui.m_spinHoursAvoid->setValue(fd->hoursToAvoid());
m_ui.m_cbDisableFeed->setChecked(fd->isSwitchedOff());
m_ui.m_cbSuppressFeed->setChecked(fd->isQuiet());
- if (fd->datetimeToAvoid().isValid() && fd->datetimeToAvoid().toMSecsSinceEpoch() > 0) {
- m_ui.m_rbAvoidAbsolute->setChecked(true);
- }
- else {
- m_ui.m_rbAvoidRelative->setChecked(true);
- }
+ ArticleAmountControl::Setup art_limit;
+
+ art_limit.m_addAnyArticlesToDb = fd->addAnyDatetimeArticles();
+ art_limit.m_avoidOldArticles =
+ (fd->datetimeToAvoid().isValid() && fd->datetimeToAvoid().toMSecsSinceEpoch() > 0) || fd->hoursToAvoid() > 0;
+ art_limit.m_dtToAvoid = fd->datetimeToAvoid();
+ art_limit.m_hoursToAvoid = fd->hoursToAvoid();
+
+ art_limit.m_doNotRemoveStarred = false;
+ art_limit.m_doNotRemoveUnread = false;
+ art_limit.m_keepCountOfArticles = 4;
+ art_limit.m_moveToBinDontPurge = false;
+
+ m_ui.m_wdgArticleLimiting->load(art_limit);
}
void FormFeedDetails::acceptIfPossible() {
@@ -205,12 +184,6 @@ void FormFeedDetails::acceptIfPossible() {
void FormFeedDetails::initialize() {
m_ui.setupUi(this);
- m_ui.m_dtDateTimeToAvoid->setEnabled(false);
- m_ui.m_spinHoursAvoid->setEnabled(false);
- m_ui.m_spinHoursAvoid->setMode(TimeSpinBox::Mode::DaysHours);
- m_ui.m_dtDateTimeToAvoid
- ->setDisplayFormat(qApp->localization()->loadedLocale().dateTimeFormat(QLocale::FormatType::ShortFormat));
-
// Setup auto-update options.
m_ui.m_spinAutoUpdateInterval->setMode(TimeSpinBox::Mode::MinutesSeconds);
m_ui.m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL);
diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.ui b/src/librssguard/services/abstract/gui/formfeeddetails.ui
index 2f924a859..eea8c49b8 100644
--- a/src/librssguard/services/abstract/gui/formfeeddetails.ui
+++ b/src/librssguard/services/abstract/gui/formfeeddetails.ui
@@ -88,126 +88,7 @@
-
-
-
-
- 150
- 0
-
-
-
- Qt::Horizontal
-
-
-
- -
-
-
-
-
-
- -
-
-
- Add articles with any date into the database
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
- true
-
-
- Avoid adding articles before this date/time into the database
-
-
- true
-
-
-
-
-
-
-
- 1
- 0
-
-
-
-
- 1971
- 1
- 1
-
-
-
- true
-
-
-
- -
-
-
- Absolute date/time
-
-
-
- -
-
-
-
- 1
- 0
-
-
-
- 10000.000000000000000
-
-
-
- -
-
-
- Relative time
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
+
@@ -288,12 +169,15 @@
QCheckBox
+
+ ArticleAmountControl
+ QWidget
+
+ 1
+
m_cbOpenArticlesAutomatically
- m_cbAddAnyDateArticles
- m_gbAvoidOldArticles
- m_dtDateTimeToAvoid
m_cbSuppressFeed
m_cbDisableFeed
m_cbFeedRTL
@@ -316,37 +200,5 @@
-
- m_rbAvoidAbsolute
- toggled(bool)
- m_dtDateTimeToAvoid
- setEnabled(bool)
-
-
- 112
- 487
-
-
- 233
- 487
-
-
-
-
- m_rbAvoidRelative
- toggled(bool)
- m_spinHoursAvoid
- setEnabled(bool)
-
-
- 112
- 515
-
-
- 233
- 515
-
-
-