From c2f767ea5591278d09c5a9e589b86f486ccf42c0 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Wed, 10 Jan 2024 11:37:37 +0100 Subject: [PATCH] fix #1268 --- .../gui/settings/settingsfeedsmessages.cpp | 16 +++ .../gui/settings/settingsfeedsmessages.ui | 11 +- .../qtextbrowser/textbrowserviewer.cpp | 102 +++++++++++++++++- .../qtextbrowser/textbrowserviewer.h | 2 + src/librssguard/miscellaneous/settings.cpp | 3 + src/librssguard/miscellaneous/settings.h | 3 + 6 files changed, 134 insertions(+), 3 deletions(-) diff --git a/src/librssguard/gui/settings/settingsfeedsmessages.cpp b/src/librssguard/gui/settings/settingsfeedsmessages.cpp index b26b54f81..aeee0aff4 100644 --- a/src/librssguard/gui/settings/settingsfeedsmessages.cpp +++ b/src/librssguard/gui/settings/settingsfeedsmessages.cpp @@ -104,6 +104,7 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkUpdateAllFeedsOnStartup, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); + connect(m_ui->m_cbLegacyArticleFormatting, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_spinAutoUpdateInterval, static_cast(&QDoubleSpinBox::valueChanged), this, @@ -252,6 +253,10 @@ void SettingsFeedsMessages::changeFont(QLabel& lbl) { void SettingsFeedsMessages::loadSettings() { onBeginLoadSettings(); + if (!qApp->usingLite()) { + m_ui->m_cbLegacyArticleFormatting->setVisible(false); + } + m_ui->m_spinRelativeArticleTime ->setValue(settings()->value(GROUP(Messages), SETTING(Messages::RelativeTimeForNewerArticles)).toInt()); m_ui->m_spinPaddingRowsMessages @@ -282,6 +287,11 @@ void SettingsFeedsMessages::loadSettings() { m_ui->m_spinAutoUpdateInterval->setValue(settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt()); m_ui->m_spinFeedUpdateTimeout->setValue(settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt()); + if (qApp->usingLite()) { + m_ui->m_cbLegacyArticleFormatting + ->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::UseLegacyArticleFormat)).toBool()); + } + m_ui->m_dtDateTimeToAvoid->setEnabled(false); m_ui->m_spinHoursAvoid->setEnabled(false); @@ -413,6 +423,12 @@ void SettingsFeedsMessages::saveSettings() { settings()->setValue(GROUP(Messages), Messages::AvoidOldArticles, m_ui->m_gbAvoidOldArticles->isChecked()); + if (qApp->usingLite()) { + settings()->setValue(GROUP(Messages), + Messages::UseLegacyArticleFormat, + m_ui->m_cbLegacyArticleFormatting->isChecked()); + } + if (m_ui->m_rbAvoidAbsolute->isChecked()) { settings()->setValue(GROUP(Messages), Messages::DateTimeToAvoidArticle, m_ui->m_dtDateTimeToAvoid->dateTime()); settings()->setValue(GROUP(Messages), Messages::HoursToAvoidArticle, 0); diff --git a/src/librssguard/gui/settings/settingsfeedsmessages.ui b/src/librssguard/gui/settings/settingsfeedsmessages.ui index d54523a8c..bd570aa6b 100644 --- a/src/librssguard/gui/settings/settingsfeedsmessages.ui +++ b/src/librssguard/gui/settings/settingsfeedsmessages.ui @@ -386,14 +386,14 @@ - + Bring application window to front once article is opened in external web browser - + Internal article viewer @@ -499,6 +499,13 @@ + + + + Use legacy article formatting + + + diff --git a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp index ae5888c3e..e7f5a270c 100644 --- a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp +++ b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.cpp @@ -250,7 +250,9 @@ void TextBrowserViewer::loadMessages(const QList& messages, RootItem* r m_root = root; auto html_messages = - qApp->skins()->generateHtmlOfArticles(messages, root, width() * ACCEPTABLE_IMAGE_PERCENTUAL_WIDTH); + qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseLegacyArticleFormat)).toBool() + ? prepareLegacyHtmlForMessage(messages, root) + : qApp->skins()->generateHtmlOfArticles(messages, root, width() * ACCEPTABLE_IMAGE_PERCENTUAL_WIDTH); // Remove other characters which cannot be displayed properly. static QRegularExpression exp_symbols("[0-9A-F]{3};"); @@ -535,6 +537,104 @@ void TextBrowserViewer::resourceDownloaded(const QUrl& url, downloadNextNeededResource(); } +PreparedHtml TextBrowserViewer::prepareLegacyHtmlForMessage(const QList& messages, RootItem* selected_item) const { + PreparedHtml html; + bool acc_displays_enclosures = + selected_item == nullptr || selected_item->getParentServiceRoot()->displaysEnclosures(); + + for (const Message& message : messages) { + bool is_plain = !TextFactory::couldBeHtml(message.m_contents); + + // Add title. + if (!message.m_url.isEmpty()) { + html.m_html += QSL("

%1

").arg(message.m_title, message.m_url); + } + else { + html.m_html += QSL("

%1

").arg(message.m_title); + } + + // Start contents. + html.m_html += QSL("
"); + + // Add links to enclosures. + if (acc_displays_enclosures) { + for (const Enclosure& enc : message.m_enclosures) { + html.m_html += QSL("[%2]").arg(enc.m_url, enc.m_mimeType); + } + } + + // Display enclosures which are pictures if user has it enabled. + auto first_enc_break_added = false; + + if (acc_displays_enclosures && + qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayEnclosuresInMessage)).toBool()) { + for (const Enclosure& enc : message.m_enclosures) { + if (enc.m_mimeType.startsWith(QSL("image/"))) { + if (!first_enc_break_added) { + html.m_html += QSL("
"); + first_enc_break_added = true; + } + + html.m_html += QSL("
").arg(enc.m_url); + } + } + } + + // Append actual contents of article and convert to HTML if needed. + html.m_html += is_plain ? Qt::convertFromPlainText(message.m_contents, Qt::WhiteSpaceMode::WhiteSpaceNormal) + : message.m_contents; + + static QRegularExpression img_tag_rgx(QSL("\\]*src\\s*=\\s*[\"\']([^\"\']*)[\"\'][^\\>]*\\>"), + QRegularExpression::PatternOption::CaseInsensitiveOption | + QRegularExpression::PatternOption::InvertedGreedinessOption); + + // Extract all images links from article to be appended to end of article. + QRegularExpressionMatchIterator i = img_tag_rgx.globalMatch(html.m_html); + QString pictures_html; + + while (i.hasNext()) { + QRegularExpressionMatch match = i.next(); + auto captured_url = match.captured(1); + + pictures_html += QSL("
[%1] %2").arg(tr("image"), captured_url); + } + + // Make alla images clickable as links and also resize them if user has it setup. + auto forced_img_size = + qApp->settings()->value(GROUP(Messages), SETTING(Messages::LimitArticleImagesHeight)).toInt(); + + // Fixup all "img" tags. + html.m_html = html.m_html.replace(img_tag_rgx, + QSL("") + .arg(forced_img_size <= 0 ? QString() : QString::number(forced_img_size))); + + // Append generated list of images. + html.m_html += pictures_html; + } + + // Close contents. + html.m_html += QSL("
"); + + QString base_url; + auto* feed = selected_item->getParentServiceRoot() + ->getItemFromSubTree([messages](const RootItem* it) { + return it->kind() == RootItem::Kind::Feed && it->customId() == messages.at(0).m_feedId; + }) + ->toFeed(); + + if (feed != nullptr) { + QUrl url(NetworkFactory::sanitizeUrl(feed->source())); + + if (url.isValid()) { + base_url = url.scheme() + QSL("://") + url.host(); + } + } + + html.m_baseUrl = base_url; + + return html; +} + bool TextBrowserViewer::resourcesEnabled() const { return m_resourcesEnabled; } diff --git a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h index b6c2efe35..a7b972a8a 100644 --- a/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h +++ b/src/librssguard/gui/webviewers/qtextbrowser/textbrowserviewer.h @@ -94,6 +94,8 @@ class TextBrowserViewer : public QTextBrowser, public WebViewer { void closeWindowRequested(); private: + PreparedHtml prepareLegacyHtmlForMessage(const QList& messages, RootItem* selected_item) const; + void setHtmlPrivate(const QString& html, const QUrl& base_url); BlockingResult blockedWithAdblock(const QUrl& url); diff --git a/src/librssguard/miscellaneous/settings.cpp b/src/librssguard/miscellaneous/settings.cpp index c17a8092a..7a21ef89a 100644 --- a/src/librssguard/miscellaneous/settings.cpp +++ b/src/librssguard/miscellaneous/settings.cpp @@ -143,6 +143,9 @@ DKEY Messages::ID = "messages"; DKEY Messages::LimitArticleImagesHeight = "message_head_image_height"; DVALUE(int) Messages::LimitArticleImagesHeightDef = 72; +DKEY Messages::UseLegacyArticleFormat = "legacy_article_format"; +DVALUE(bool) Messages::UseLegacyArticleFormatDef = false; + DKEY Messages::DisplayEnclosuresInMessage = "show_enclosures_in_message"; DVALUE(bool) Messages::DisplayEnclosuresInMessageDef = false; diff --git a/src/librssguard/miscellaneous/settings.h b/src/librssguard/miscellaneous/settings.h index 88ad16dcd..424388e28 100644 --- a/src/librssguard/miscellaneous/settings.h +++ b/src/librssguard/miscellaneous/settings.h @@ -140,6 +140,9 @@ namespace Messages { KEY LimitArticleImagesHeight; VALUE(int) LimitArticleImagesHeightDef; + KEY UseLegacyArticleFormat; + VALUE(bool) UseLegacyArticleFormatDef; + KEY DisplayEnclosuresInMessage; VALUE(bool) DisplayEnclosuresInMessageDef;