diff --git a/resources/sql.qrc b/resources/sql.qrc index 0187a0294..b669edc27 100644 --- a/resources/sql.qrc +++ b/resources/sql.qrc @@ -8,6 +8,7 @@ sql/db_update_mysql_5_6.sql sql/db_update_mysql_6_7.sql sql/db_update_mysql_7_8.sql + sql/db_update_mysql_8_9.sql sql/db_init_sqlite.sql sql/db_update_sqlite_1_2.sql @@ -17,5 +18,6 @@ sql/db_update_sqlite_5_6.sql sql/db_update_sqlite_6_7.sql sql/db_update_sqlite_7_8.sql + sql/db_update_sqlite_8_9.sql \ No newline at end of file diff --git a/resources/sql/db_init_sqlite.sql b/resources/sql/db_init_sqlite.sql index 928cfed4b..62af2450c 100644 --- a/resources/sql/db_init_sqlite.sql +++ b/resources/sql/db_init_sqlite.sql @@ -43,7 +43,7 @@ CREATE TABLE Feeds ( 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), + is_rtl INTEGER NOT NULL DEFAULT 0 CHECK (is_rtl >= 0 AND is_rtl <= 1024), 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), diff --git a/resources/sql/db_update_mysql_8_9.sql b/resources/sql/db_update_mysql_8_9.sql new file mode 100644 index 000000000..b1d5f46f3 --- /dev/null +++ b/resources/sql/db_update_mysql_8_9.sql @@ -0,0 +1,7 @@ +USE ##; +-- ! +SET FOREIGN_KEY_CHECKS = 0; +-- ! +!! db_update_sqlite_8_9.sql +-- ! +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/resources/sql/db_update_sqlite_8_9.sql b/resources/sql/db_update_sqlite_8_9.sql new file mode 100644 index 000000000..6edfa8e1f --- /dev/null +++ b/resources/sql/db_update_sqlite_8_9.sql @@ -0,0 +1,40 @@ +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 <= 1024), + + 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_customize INTEGER NOT NULL DEFAULT 0 CHECK (keep_article_customize >= 0 AND keep_article_customize <= 1), + 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, keep_article_customize, keep_article_count, keep_unread_articles, keep_starred_articles, recycle_articles, 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, keep_article_customize, keep_article_count, keep_unread_articles, keep_starred_articles, recycle_articles, 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/CMakeLists.txt b/src/librssguard/CMakeLists.txt index 5d0e9dabe..87a3440f1 100644 --- a/src/librssguard/CMakeLists.txt +++ b/src/librssguard/CMakeLists.txt @@ -297,6 +297,7 @@ set(SOURCES services/abstract/category.h services/abstract/feed.cpp services/abstract/feed.h + services/abstract/feedrtlbehavior.h services/abstract/gui/accountdetails.cpp services/abstract/gui/accountdetails.h services/abstract/gui/authenticationdetails.cpp diff --git a/src/librssguard/core/message.cpp b/src/librssguard/core/message.cpp index a99af51eb..e42540664 100644 --- a/src/librssguard/core/message.cpp +++ b/src/librssguard/core/message.cpp @@ -111,7 +111,8 @@ Message::Message() { m_categories = QList(); m_accountId = m_id = 0; m_score = 0.0; - m_isRead = m_isImportant = m_isDeleted = m_isRtl = false; + m_isRead = m_isImportant = m_isDeleted = false; + m_rtlBehavior = RtlBehavior::NoRtl; m_assignedLabels = QList(); m_assignedLabelsByFilter = QList(); m_deassignedLabelsByFilter = QList(); @@ -188,7 +189,7 @@ QJsonObject Message::toJson() const { obj.insert(QSL("custom_hash"), m_customHash); obj.insert(QSL("feed_custom_id"), m_feedId); obj.insert(QSL("feed_title"), m_feedTitle); - obj.insert(QSL("is_rtl"), m_isRtl); + obj.insert(QSL("is_rtl"), int(m_rtlBehavior)); obj.insert(QSL("enclosures"), Enclosures::encodeEnclosuresToJson(m_enclosures)); return obj; @@ -218,7 +219,7 @@ Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) { message.m_contents = record.value(MSG_DB_CONTENTS_INDEX).toString(); message.m_enclosures = Enclosures::decodeEnclosuresFromString(record.value(MSG_DB_ENCLOSURES_INDEX).toString()); message.m_score = record.value(MSG_DB_SCORE_INDEX).toDouble(); - message.m_isRtl = record.value(MSG_DB_FEED_IS_RTL_INDEX).toBool(); + message.m_rtlBehavior = record.value(MSG_DB_FEED_IS_RTL_INDEX).value(); message.m_accountId = record.value(MSG_DB_ACCOUNT_ID_INDEX).toInt(); message.m_customId = record.value(MSG_DB_CUSTOM_ID_INDEX).toString(); message.m_customHash = record.value(MSG_DB_CUSTOM_HASH_INDEX).toString(); @@ -258,7 +259,7 @@ QString Message::generateRawAtomContents(const Message& msg) { QDataStream& operator<<(QDataStream& out, const Message& my_obj) { out << my_obj.m_accountId << my_obj.m_customHash << my_obj.m_customId << my_obj.m_feedId << my_obj.m_id - << my_obj.m_isImportant << my_obj.m_isRead << my_obj.m_isDeleted << my_obj.m_score << my_obj.m_isRtl; + << my_obj.m_isImportant << my_obj.m_isRead << my_obj.m_isDeleted << my_obj.m_score << my_obj.m_rtlBehavior; return out; } @@ -272,7 +273,7 @@ QDataStream& operator>>(QDataStream& in, Message& my_obj) { bool is_important; bool is_read; bool is_deleted; - bool is_rtl; + RtlBehavior is_rtl; double score; in >> account_id >> custom_hash >> custom_id >> feed_id >> id >> is_important >> is_read >> is_deleted >> score >> @@ -287,7 +288,7 @@ QDataStream& operator>>(QDataStream& in, Message& my_obj) { my_obj.m_isRead = is_read; my_obj.m_isDeleted = is_deleted; my_obj.m_score = score; - my_obj.m_isRtl = is_rtl; + my_obj.m_rtlBehavior = is_rtl; return in; } diff --git a/src/librssguard/core/message.h b/src/librssguard/core/message.h index 9364c82fa..a9eb14327 100644 --- a/src/librssguard/core/message.h +++ b/src/librssguard/core/message.h @@ -5,6 +5,8 @@ // #include "definitions/definitions.h" +#include "services/abstract/feedrtlbehavior.h" + #include #include #include @@ -84,7 +86,7 @@ class RSSGUARD_DLLSPEC Message { bool m_isImportant; bool m_isDeleted; double m_score; - bool m_isRtl; + RtlBehavior m_rtlBehavior; QList m_enclosures; // List of assigned labels. diff --git a/src/librssguard/core/messagesmodel.cpp b/src/librssguard/core/messagesmodel.cpp index 58bb35f50..3737f38b6 100644 --- a/src/librssguard/core/messagesmodel.cpp +++ b/src/librssguard/core/messagesmodel.cpp @@ -437,12 +437,15 @@ QVariant MessagesModel::data(const QModelIndex& idx, int role) const { return Qt::LayoutDirection::LayoutDirectionAuto; } else { - return (m_cache->containsData(idx.row()) - ? m_cache->data(index(idx.row(), MSG_DB_FEED_IS_RTL_INDEX)) - : QSqlQueryModel::data(index(idx.row(), MSG_DB_FEED_IS_RTL_INDEX), Qt::ItemDataRole::EditRole)) - .toInt() == 0 - ? Qt::LayoutDirection::LayoutDirectionAuto - : Qt::LayoutDirection::RightToLeft; + RtlBehavior rtl_mode = + (m_cache->containsData(idx.row()) + ? m_cache->data(index(idx.row(), MSG_DB_FEED_IS_RTL_INDEX)) + : QSqlQueryModel::data(index(idx.row(), MSG_DB_FEED_IS_RTL_INDEX), Qt::ItemDataRole::EditRole)) + .value(); + + return (rtl_mode == RtlBehavior::Everywhere || rtl_mode == RtlBehavior::EverywhereExceptFeedList) + ? Qt::LayoutDirection::RightToLeft + : Qt::LayoutDirection::LayoutDirectionAuto; } } diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index ea932eb63..a5494a568 100644 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -2698,7 +2698,7 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in q.bindValue(QSL(":is_off"), feed->isSwitchedOff()); q.bindValue(QSL(":is_quiet"), feed->isQuiet()); q.bindValue(QSL(":open_articles"), feed->openArticlesDirectly()); - q.bindValue(QSL(":is_rtl"), feed->isRtl()); + q.bindValue(QSL(":is_rtl"), int(feed->rtlBehavior())); const Feed::ArticleIgnoreLimit art = feed->articleIgnoreLimit(); diff --git a/src/librssguard/database/databasequeries.h b/src/librssguard/database/databasequeries.h index 7bac62947..211c3029c 100644 --- a/src/librssguard/database/databasequeries.h +++ b/src/librssguard/database/databasequeries.h @@ -385,7 +385,7 @@ Assignment DatabaseQueries::getFeeds(const QSqlDatabase& db, feed->setAutoUpdateInterval(query.value(FDS_DB_UPDATE_INTERVAL_INDEX).toInt()); feed->setIsSwitchedOff(query.value(FDS_DB_IS_OFF_INDEX).toBool()); feed->setIsQuiet(query.value(FDS_DB_IS_QUIET_INDEX).toBool()); - feed->setIsRtl(query.value(FDS_DB_IS_RTL_INDEX).toBool()); + feed->setRtlBehavior(query.value(FDS_DB_IS_RTL_INDEX).value()); Feed::ArticleIgnoreLimit art; diff --git a/src/librssguard/definitions/definitions.h b/src/librssguard/definitions/definitions.h index 73b017eec..4c5227138 100644 --- a/src/librssguard/definitions/definitions.h +++ b/src/librssguard/definitions/definitions.h @@ -230,7 +230,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 "8" +#define APP_DB_SCHEMA_VERSION "9" #define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql" #define APP_DB_COMMENT_SPLIT "-- !\n" #define APP_DB_INCLUDE_PLACEHOLDER "!!" diff --git a/src/librssguard/gui/messagesview.cpp b/src/librssguard/gui/messagesview.cpp index a4c7942ed..6bffe750a 100644 --- a/src/librssguard/gui/messagesview.cpp +++ b/src/librssguard/gui/messagesview.cpp @@ -592,19 +592,24 @@ void MessagesView::loadItem(RootItem* item) { if (switch_entire_rtl_list && item != nullptr) { if (item->kind() == RootItem::Kind::Feed) { - setLayoutDirection(item->toFeed()->isRtl() ? Qt::LayoutDirection::RightToLeft : Qt::LayoutDirection::LeftToRight); + auto* fd = item->toFeed(); + setLayoutDirection((fd->rtlBehavior() == RtlBehavior::Everywhere || + fd->rtlBehavior() == RtlBehavior::EverywhereExceptFeedList) + ? Qt::LayoutDirection::RightToLeft + : Qt::LayoutDirection::LayoutDirectionAuto); } else { auto fds = item->getSubTreeFeeds(); bool all_feeds_rtl = !fds.isEmpty() && std::all_of(fds.begin(), fds.end(), [](Feed* fd) { - return fd->isRtl(); + return fd->rtlBehavior() == RtlBehavior::Everywhere || + fd->rtlBehavior() == RtlBehavior::EverywhereExceptFeedList; }); - setLayoutDirection(all_feeds_rtl ? Qt::LayoutDirection::RightToLeft : Qt::LayoutDirection::LeftToRight); + setLayoutDirection(all_feeds_rtl ? Qt::LayoutDirection::RightToLeft : Qt::LayoutDirection::LayoutDirectionAuto); } } else { - setLayoutDirection(Qt::LayoutDirection::LeftToRight); + setLayoutDirection(Qt::LayoutDirection::LayoutDirectionAuto); } // Messages are loaded, make sure that previously diff --git a/src/librssguard/gui/webbrowser.cpp b/src/librssguard/gui/webbrowser.cpp index 149a9a698..c8ad4feca 100644 --- a/src/librssguard/gui/webbrowser.cpp +++ b/src/librssguard/gui/webbrowser.cpp @@ -369,7 +369,7 @@ void WebBrowser::setFullArticleHtml(const QObject* sndr, const QString& url, con full_article.m_isImportant = displayed_article.m_isImportant; full_article.m_isDeleted = displayed_article.m_isDeleted; full_article.m_score = displayed_article.m_score; - full_article.m_isRtl = displayed_article.m_isRtl; + full_article.m_rtlBehavior = displayed_article.m_rtlBehavior; full_article.m_enclosures = displayed_article.m_enclosures; loadMessages({full_article}, m_root); diff --git a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp index 2decf10c4..dd21178a8 100644 --- a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp +++ b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp @@ -295,7 +295,11 @@ void TextBrowserViewer::loadMessages(const QList& messages, RootItem* r setHtml(html_messages.m_html, html_messages.m_baseUrl); QTextOption op; - op.setTextDirection(messages.at(0).m_isRtl ? Qt::LayoutDirection::RightToLeft : Qt::LayoutDirection::LeftToRight); + op.setTextDirection((messages.at(0).m_rtlBehavior == RtlBehavior::Everywhere || + messages.at(0).m_rtlBehavior == RtlBehavior::EverywhereExceptFeedList || + messages.at(0).m_rtlBehavior == RtlBehavior::OnlyViewer) + ? Qt::LayoutDirection::RightToLeft + : Qt::LayoutDirection::LeftToRight); document()->setDefaultTextOption(op); emit loadingFinished(true); diff --git a/src/librssguard/miscellaneous/skinfactory.cpp b/src/librssguard/miscellaneous/skinfactory.cpp index 58fbd5b06..906ef5679 100644 --- a/src/librssguard/miscellaneous/skinfactory.cpp +++ b/src/librssguard/miscellaneous/skinfactory.cpp @@ -292,17 +292,21 @@ PreparedHtml SkinFactory::generateHtmlOfArticles(const QList& messages, msg_contents = qApp->web()->limitSizeOfHtmlImages(msg_contents, desired_width, forced_img_height); } - messages_layout.append(single_message_layout.arg(message.m_title, - tr("Written by ") + (message.m_author.isEmpty() - ? tr("unknown author") - : message.m_author), - message.m_url, - msg_contents, - msg_date, - enclosures, - enclosure_images, - QString::number(message.m_id), - message.m_isRtl ? QSL("rtl") : QSL("ltr"))); + messages_layout + .append(single_message_layout.arg(message.m_title, + tr("Written by ") + + (message.m_author.isEmpty() ? tr("unknown author") : message.m_author), + message.m_url, + msg_contents, + msg_date, + enclosures, + enclosure_images, + QString::number(message.m_id), + (message.m_rtlBehavior == RtlBehavior::Everywhere || + message.m_rtlBehavior == RtlBehavior::EverywhereExceptFeedList || + message.m_rtlBehavior == RtlBehavior::OnlyViewer) + ? QSL("rtl") + : QSL("ltr"))); } QString msg_contents = diff --git a/src/librssguard/services/abstract/FeedRtlBehavior.h b/src/librssguard/services/abstract/FeedRtlBehavior.h new file mode 100644 index 000000000..cb20f983b --- /dev/null +++ b/src/librssguard/services/abstract/FeedRtlBehavior.h @@ -0,0 +1,17 @@ +// For license of this file, see /LICENSE.md. + +#ifndef FEEDRTLBEHAVIOR_H +#define FEEDRTLBEHAVIOR_H + +#include + +enum class RtlBehavior { + NoRtl = 0, // The item is not RTL. + Everywhere = 1, // RTL is applied everwhere (feed list, article list, article viewer). + OnlyViewer = 2, // Use RTL only in article view, but not in article/feed list. + EverywhereExceptFeedList = 4 // Use RTL everywhere, but not in the feed list. +}; + +Q_DECLARE_METATYPE(RtlBehavior) + +#endif // FEEDRTLBEHAVIOR_H diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index d6ade82de..d0ce0a172 100644 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -17,7 +17,8 @@ Feed::Feed(RootItem* parent) : RootItem(parent), m_source(QString()), m_status(Status::Normal), m_statusString(QString()), m_autoUpdateType(AutoUpdateType::DefaultAutoUpdate), m_autoUpdateInterval(DEFAULT_AUTO_UPDATE_INTERVAL), m_lastUpdated(QDateTime::currentDateTimeUtc()), m_isSwitchedOff(false), m_isQuiet(false), - m_openArticlesDirectly(false), m_isRtl(false), m_messageFilters(QList>()) { + m_openArticlesDirectly(false), m_rtlBehavior(RtlBehavior::NoRtl), + m_messageFilters(QList>()) { setKind(RootItem::Kind::Feed); } @@ -40,7 +41,7 @@ Feed::Feed(const Feed& other) : RootItem(other) { setMessageFilters(other.messageFilters()); setOpenArticlesDirectly(other.openArticlesDirectly()); setArticleIgnoreLimit(Feed::ArticleIgnoreLimit(other.articleIgnoreLimit())); - setIsRtl(other.isRtl()); + setRtlBehavior(other.rtlBehavior()); setIsSwitchedOff(other.isSwitchedOff()); setIsQuiet(other.isQuiet()); } @@ -78,7 +79,8 @@ QVariant Feed::data(int column, int role) const { case TEXT_DIRECTION_ROLE: { if (column == FDS_MODEL_TITLE_INDEX) { - return isRtl() ? Qt::LayoutDirection::RightToLeft : Qt::LayoutDirection::LayoutDirectionAuto; + return rtlBehavior() == RtlBehavior::Everywhere ? Qt::LayoutDirection::RightToLeft + : Qt::LayoutDirection::LayoutDirectionAuto; } else { return Qt::LayoutDirection::LayoutDirectionAuto; @@ -198,12 +200,12 @@ void Feed::setOpenArticlesDirectly(bool opn) { m_openArticlesDirectly = opn; } -bool Feed::isRtl() const { - return m_isRtl; +RtlBehavior Feed::rtlBehavior() const { + return m_rtlBehavior; } -void Feed::setIsRtl(bool rtl) { - m_isRtl = rtl; +void Feed::setRtlBehavior(RtlBehavior rtl) { + m_rtlBehavior = rtl; } bool Feed::removeUnwantedArticles(QSqlDatabase& db) { diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index 787e4ece9..a442ee3af 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -5,6 +5,7 @@ #include "core/message.h" #include "core/messagefilter.h" +#include "services/abstract/feedrtlbehavior.h" #include "services/abstract/rootitem.h" #include @@ -104,8 +105,8 @@ class RSSGUARD_DLLSPEC Feed : public RootItem { QDateTime lastUpdated() const; void setLastUpdated(const QDateTime& last_updated); - bool isRtl() const; - void setIsRtl(bool rtl); + RtlBehavior rtlBehavior() const; + void setRtlBehavior(RtlBehavior rtl); bool removeUnwantedArticles(QSqlDatabase& db); @@ -130,7 +131,7 @@ class RSSGUARD_DLLSPEC Feed : public RootItem { bool m_isSwitchedOff; bool m_isQuiet; bool m_openArticlesDirectly; - bool m_isRtl; + RtlBehavior m_rtlBehavior; // NOTE: These are used to filter out older articles // than needed. Either absolute value is given (date/time) diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.cpp b/src/librssguard/services/abstract/gui/formfeeddetails.cpp index 48429c40d..65ed65312 100644 --- a/src/librssguard/services/abstract/gui/formfeeddetails.cpp +++ b/src/librssguard/services/abstract/gui/formfeeddetails.cpp @@ -61,7 +61,7 @@ void FormFeedDetails::apply() { } if (isChangeAllowed(m_ui->m_mcbFeedRtl)) { - fd->setIsRtl(m_ui->m_cbFeedRtl->isChecked()); + fd->setRtlBehavior(m_ui->m_cmbRtlBehavior->currentData().value()); } m_ui->m_wdgArticleLimiting->saveFeed(fd, m_isBatchEdit); @@ -127,7 +127,7 @@ void FormFeedDetails::loadFeedData() { m_ui->m_mcbOpenArticlesAutomatically->addActionWidget(m_ui->m_cbOpenArticlesAutomatically); 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_mcbFeedRtl->addActionWidget(m_ui->m_cmbRtlBehavior); } else { // We hide batch selectors. @@ -158,7 +158,7 @@ void FormFeedDetails::loadFeedData() { ->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue(int(fd->autoUpdateType())))); m_ui->m_spinAutoUpdateInterval->setValue(fd->autoUpdateInterval()); m_ui->m_cbOpenArticlesAutomatically->setChecked(fd->openArticlesDirectly()); - m_ui->m_cbFeedRtl->setChecked(fd->isRtl()); + m_ui->m_cmbRtlBehavior->setCurrentIndex(m_ui->m_cmbRtlBehavior->findData(QVariant::fromValue(fd->rtlBehavior()))); m_ui->m_cbDisableFeed->setChecked(fd->isSwitchedOff()); m_ui->m_cbSuppressFeed->setChecked(fd->isQuiet()); @@ -202,10 +202,18 @@ void FormFeedDetails::initialize() { // Setup auto-update options. m_ui->m_spinAutoUpdateInterval->setMode(TimeSpinBox::Mode::MinutesSeconds); m_ui->m_spinAutoUpdateInterval->setValue(DEFAULT_AUTO_UPDATE_INTERVAL); + m_ui->m_cmbAutoUpdateType->addItem(tr("Fetch articles using global interval"), QVariant::fromValue(int(Feed::AutoUpdateType::DefaultAutoUpdate))); m_ui->m_cmbAutoUpdateType->addItem(tr("Fetch articles every"), QVariant::fromValue(int(Feed::AutoUpdateType::SpecificAutoUpdate))); m_ui->m_cmbAutoUpdateType->addItem(tr("Disable auto-fetching of articles"), QVariant::fromValue(int(Feed::AutoUpdateType::DontAutoUpdate))); + + m_ui->m_cmbRtlBehavior->addItem(tr("Left-to-right"), QVariant::fromValue(int(RtlBehavior::NoRtl))); + m_ui->m_cmbRtlBehavior->addItem(tr("Right-to-left (everywhere)"), QVariant::fromValue(int(RtlBehavior::Everywhere))); + m_ui->m_cmbRtlBehavior->addItem(tr("Right-to-left (everywhere except feed list)"), + QVariant::fromValue(int(RtlBehavior::EverywhereExceptFeedList))); + m_ui->m_cmbRtlBehavior->addItem(tr("Right-to-left (only in article viewer)"), + QVariant::fromValue(int(RtlBehavior::OnlyViewer))); } diff --git a/src/librssguard/services/abstract/gui/formfeeddetails.ui b/src/librssguard/services/abstract/gui/formfeeddetails.ui index 5aa85fc89..292e3c728 100644 --- a/src/librssguard/services/abstract/gui/formfeeddetails.ui +++ b/src/librssguard/services/abstract/gui/formfeeddetails.ui @@ -131,11 +131,18 @@ - - - Right-to-left layout - - + + + + + Right-to-left behavior + + + + + + + @@ -188,7 +195,6 @@ m_mcbDisableFeed m_cbDisableFeed m_mcbFeedRtl - m_cbFeedRtl diff --git a/src/librssguard/services/abstract/serviceroot.cpp b/src/librssguard/services/abstract/serviceroot.cpp index d5d78a0cd..2507551d6 100644 --- a/src/librssguard/services/abstract/serviceroot.cpp +++ b/src/librssguard/services/abstract/serviceroot.cpp @@ -491,7 +491,7 @@ QMap ServiceRoot::storeCustomFeedsData() { feed_custom_data.insert(QSL("is_off"), feed->isSwitchedOff()); feed_custom_data.insert(QSL("is_quiet"), feed->isQuiet()); feed_custom_data.insert(QSL("open_articles_directly"), feed->openArticlesDirectly()); - feed_custom_data.insert(QSL("is_rtl"), feed->isRtl()); + feed_custom_data.insert(QSL("is_rtl"), QVariant::fromValue(feed->rtlBehavior())); feed_custom_data.insert(QSL("article_limit_ignore"), QVariant::fromValue(feed->articleIgnoreLimit())); @@ -550,7 +550,7 @@ void ServiceRoot::restoreCustomFeedsData(const QMap& data, feed->setIsSwitchedOff(feed_custom_data.value(QSL("is_off")).toBool()); feed->setIsQuiet(feed_custom_data.value(QSL("is_quiet")).toBool()); feed->setOpenArticlesDirectly(feed_custom_data.value(QSL("open_articles_directly")).toBool()); - feed->setIsRtl(feed_custom_data.value(QSL("is_rtl")).toBool()); + feed->setRtlBehavior(feed_custom_data.value(QSL("is_rtl")).value()); feed ->setArticleIgnoreLimit(feed_custom_data.value(QSL("article_limit_ignore")).value());