New Feature: Right-to-Left Layout for Feed Articles in RTL Languages

I added a feature that lets change the feed's articles from right to left for languages such as Arabic, Urdu, Hebrew, Farsi...
To enable it :  **The desired feed -> Edit selected item -> Articles -> Right-to-left layout**.

![LTR](https://github.com/martinrotter/rssguard/assets/25085777/a555d38d-a066-44d2-b0d0-158daae4ac2b)
![RTL](https://github.com/martinrotter/rssguard/assets/25085777/81cde3e3-f645-4c2b-a46a-d60aa5f54bd7)
This commit is contained in:
رشيد 2023-07-22 16:21:23 +01:00
parent a5366e8a68
commit a8a0f789e9
12 changed files with 52 additions and 12 deletions

View File

@ -43,6 +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),
add_any_datetime_articles INTEGER NOT NULL DEFAULT 0 CHECK(add_any_datetime_articles >= 0 AND add_any_datetime_articles <= 1),
avoid_old_articles INTEGER NOT NULL DEFAULT 0 CHECK(avoid_old_articles >= 0 AND avoid_old_articles <= 1),
datetime_to_avoid BIGINT NOT NULL DEFAULT 0 CHECK (datetime_to_avoid >= 0),

View File

@ -13,6 +13,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),
add_any_datetime_articles INTEGER NOT NULL DEFAULT 0 CHECK(add_any_datetime_articles >= 0 AND add_any_datetime_articles <= 1),
avoid_old_articles INTEGER NOT NULL DEFAULT 0 CHECK(avoid_old_articles >= 0 AND avoid_old_articles <= 1),
datetime_to_avoid BIGINT NOT NULL DEFAULT 0 CHECK (datetime_to_avoid >= 0),

View File

@ -2180,7 +2180,7 @@ void DatabaseQueries::createOverwriteFeed(const QSqlDatabase& db, Feed* feed, in
"SET title = :title, ordr = :ordr, description = :description, date_created = :date_created, "
" icon = :icon, category = :category, source = :source, update_type = :update_type,"
" update_interval = :update_interval, is_off = :is_off, is_quiet = :is_quiet, open_articles ="
" :open_articles, add_any_datetime_articles = :add_any_datetime_articles,"
" :open_articles, is_rtl = :is_rtl, add_any_datetime_articles = :add_any_datetime_articles,"
" avoid_old_articles = :avoid_old_articles, datetime_to_avoid = :datetime_to_avoid, account_id"
" = :account_id, custom_id = :custom_id, custom_data = :custom_data WHERE id = :id;");
q.bindValue(QSL(":title"), feed->title());
@ -2198,6 +2198,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(":add_any_datetime_articles"), feed->addAnyDatetimeArticles());
q.bindValue(QSL(":avoid_old_articles"), feed->avoidOldArticles());
q.bindValue(QSL(":datetime_to_avoid"), feed->datetimeToAvoid().toMSecsSinceEpoch());

View File

@ -353,6 +353,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->setAddAnyDatetimeArticles(query.value(FDS_DB_ADD_ANY_DATETIME_ARTICLES_INDEX).toBool());
feed->setAvoidOldArticles(query.value(FDS_DB_AVOID_OLD_ARTICLES_INDEX).toBool());
feed->setDatetimeToAvoid(query.value(FDS_DB_DATETIME_TO_AVOID_INDEX).toDateTime());

View File

@ -295,13 +295,14 @@
#define FDS_DB_UPDATE_INTERVAL_INDEX 9
#define FDS_DB_IS_OFF_INDEX 10
#define FDS_DB_IS_QUIET_INDEX 11
#define FDS_DB_ADD_ANY_DATETIME_ARTICLES_INDEX 12
#define FDS_DB_AVOID_OLD_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_IS_RTL_INDEX 12
#define FDS_DB_ADD_ANY_DATETIME_ARTICLES_INDEX 13
#define FDS_DB_AVOID_OLD_ARTICLES_INDEX 14
#define FDS_DB_DATETIME_TO_AVOID_INDEX 15
#define FDS_DB_OPEN_ARTICLES_INDEX 16
#define FDS_DB_ACCOUNT_ID_INDEX 17
#define FDS_DB_CUSTOM_ID_INDEX 18
#define FDS_DB_CUSTOM_DATA_INDEX 19
// Indexes of columns for feed models.
#define FDS_MODEL_TITLE_INDEX 0

View File

@ -231,6 +231,10 @@ void FeedsView::editSelectedItem() {
QSystemTrayIcon::MessageIcon::Warning});
}
RootItem* selected_item = selectedItem();
emit itemSelected(selected_item);
// Changes are done, unlock the update master lock.
qApp->feedUpdateLock()->unlock();
}

View File

@ -516,6 +516,13 @@ void MessagesView::loadItem(RootItem* item) {
sort(col, ord, false, true, false, true);
m_sourceModel->loadMessages(item);
if (item->toFeed() != nullptr) {
if (item->toFeed()->isRTL())
setLayoutDirection(Qt::RightToLeft);
else
setLayoutDirection(Qt::LeftToRight);
}
// Messages are loaded, make sure that previously
// active message is not shown in browser.
emit currentMessageRemoved(m_sourceModel->loadedItem());

View File

@ -21,8 +21,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_addAnyDatetimeArticles(false), m_avoidOldArticles(false), m_datetimeToAvoid(QDateTime::currentDateTime()),
m_openArticlesDirectly(false), m_messageFilters(QList<QPointer<MessageFilter>>()) {
m_isRTL(false), m_addAnyDatetimeArticles(false), m_avoidOldArticles(false), m_openArticlesDirectly(false),
m_datetimeToAvoid(QDateTime::currentDateTime()), m_messageFilters(QList<QPointer<MessageFilter>>()) {
setKind(RootItem::Kind::Feed);
}
@ -48,6 +48,7 @@ Feed::Feed(const Feed& other) : RootItem(other) {
setAvoidOldArticles(other.avoidOldArticles());
setAvoidOldArticlesEnabled(other.isAvoidOldArticlesEnabled());
setDatetimeToAvoid(other.datetimeToAvoid());
setIsRTL(other.isRTL());
setIsSwitchedOff(other.isSwitchedOff());
setIsQuiet(other.isQuiet());
}
@ -194,6 +195,14 @@ void Feed::setOpenArticlesDirectly(bool opn) {
m_openArticlesDirectly = opn;
}
bool Feed::isRTL() const {
return m_isRTL;
}
void Feed::setIsRTL(bool rtl) {
m_isRTL = rtl;
}
bool Feed::addAnyDatetimeArticles() const {
return m_addAnyDatetimeArticles;
}

View File

@ -83,6 +83,9 @@ class Feed : public RootItem {
QDateTime lastUpdated() const;
void setLastUpdated(const QDateTime& last_updated);
bool isRTL() const;
void setIsRTL(bool rtl);
bool addAnyDatetimeArticles() const;
void setAddAnyDatetimeArticles(bool addAnyDatetimeArticles);
@ -113,6 +116,7 @@ class Feed : public RootItem {
bool m_isSwitchedOff;
bool m_isQuiet;
bool m_openArticlesDirectly;
bool m_isRTL;
bool m_addAnyDatetimeArticles;
bool m_avoidOldArticles;
bool m_avoidOldArticlesEnabled;

View File

@ -49,6 +49,7 @@ void FormFeedDetails::apply() {
.toInt()));
m_feed->setAutoUpdateInterval(int(m_ui->m_spinAutoUpdateInterval->value()));
m_feed->setOpenArticlesDirectly(m_ui->m_cbOpenArticlesAutomatically->isChecked());
m_feed->setIsRTL(m_ui->m_cbFeedRTL->isChecked());
m_feed->setAddAnyDatetimeArticles(m_ui->m_cbAddAnyDateArticles->isChecked());
m_feed->setAvoidOldArticles(m_ui->m_gbAvoidOldArticles->isChecked());
m_feed->setDatetimeToAvoid(m_ui->m_dtDateTimeToAvoid->dateTime());
@ -106,6 +107,7 @@ void FormFeedDetails::loadFeedData() {
->setCurrentIndex(m_ui->m_cmbAutoUpdateType->findData(QVariant::fromValue(int(m_feed->autoUpdateType()))));
m_ui->m_spinAutoUpdateInterval->setValue(m_feed->autoUpdateInterval());
m_ui->m_cbOpenArticlesAutomatically->setChecked(m_feed->openArticlesDirectly());
m_ui->m_cbFeedRTL->setChecked(m_feed->isRTL());
m_ui->m_cbAddAnyDateArticles->setChecked(m_feed->addAnyDatetimeArticles());
m_ui->m_gbAvoidOldArticles->setChecked(m_feed->avoidOldArticles());
m_ui->m_gbAvoidOldArticles->setEnabled(!m_feed->addAnyDatetimeArticles());

View File

@ -60,13 +60,20 @@
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="m_cbFeedRTL">
<property name="text">
<string>Right-to-left layout</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="m_cbAddAnyDateArticles">
<property name="text">
<string>Add articles with any date into the database</string>
@ -76,7 +83,7 @@
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="0" colspan="2">
<widget class="QGroupBox" name="m_gbAvoidOldArticles">
<property name="enabled">
<bool>true</bool>

View File

@ -384,6 +384,7 @@ QMap<QString, QVariantMap> 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("add_any_datetime_articles"), feed->addAnyDatetimeArticles());
feed_custom_data.insert(QSL("avoid_old_articles"), feed->avoidOldArticles());
feed_custom_data.insert(QSL("datetime_to_avoid"), feed->datetimeToAvoid().toMSecsSinceEpoch());
@ -436,6 +437,7 @@ void ServiceRoot::restoreCustomFeedsData(const QMap<QString, QVariantMap>& 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->setAddAnyDatetimeArticles(feed_custom_data.value(QSL("add_any_datetime_articles")).toBool());
feed->setAvoidOldArticles(feed_custom_data.value(QSL("avoid_date_message")).toBool());
feed->setDatetimeToAvoid(feed_custom_data.value(QSL("avoid_message_datetime")).toDateTime());