From 8e1c2d94d782b8dc48e8ed31fa14cea6a83a4364 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Tue, 15 Sep 2020 13:55:50 +0200 Subject: [PATCH] Refactor non-webengine too. --- src/librssguard/gui/messagebrowser.cpp | 194 +++++++++++++++++++++ src/librssguard/gui/messagebrowser.h | 44 +++++ src/librssguard/gui/messagepreviewer.cpp | 114 +----------- src/librssguard/gui/messagepreviewer.h | 7 +- src/librssguard/gui/messagetextbrowser.cpp | 71 -------- src/librssguard/gui/messagetextbrowser.h | 11 -- src/librssguard/gui/searchtextwidget.cpp | 12 +- src/librssguard/gui/searchtextwidget.h | 3 +- src/librssguard/gui/webbrowser.cpp | 2 +- src/librssguard/gui/webbrowser.h | 2 +- src/librssguard/librssguard.pro | 6 +- 11 files changed, 258 insertions(+), 208 deletions(-) create mode 100644 src/librssguard/gui/messagebrowser.cpp create mode 100644 src/librssguard/gui/messagebrowser.h diff --git a/src/librssguard/gui/messagebrowser.cpp b/src/librssguard/gui/messagebrowser.cpp new file mode 100644 index 000000000..05132a63d --- /dev/null +++ b/src/librssguard/gui/messagebrowser.cpp @@ -0,0 +1,194 @@ +// For license of this file, see /LICENSE.md. + +#include "gui/messagebrowser.h" + +#include "gui/messagebox.h" +#include "gui/messagetextbrowser.h" +#include "gui/searchtextwidget.h" +#include "miscellaneous/application.h" +#include "miscellaneous/settings.h" +#include "network-web/webfactory.h" +#include "services/abstract/serviceroot.h" + +#include +#include +#include +#include +#include + +MessageBrowser::MessageBrowser(QWidget* parent) + : QWidget(parent), m_txtBrowser(new MessageTextBrowser(this)), m_searchWidget(new SearchTextWidget(this)), + m_layout(new QVBoxLayout(this)) { + m_layout->setContentsMargins(3, 3, 3, 3); + m_layout->addWidget(m_txtBrowser, 1); + m_layout->addWidget(m_searchWidget); + + connect(m_searchWidget, &SearchTextWidget::searchCancelled, this, [this]() { + m_txtBrowser->textCursor().clearSelection(); + m_txtBrowser->moveCursor(QTextCursor::MoveOperation::Left); + }); + connect(m_searchWidget, &SearchTextWidget::searchForText, this, [this](const QString& text, bool backwards) { + if (backwards) { + m_txtBrowser->find(text, QTextDocument::FindFlag::FindBackward); + } + else { + m_txtBrowser->find(text); + } + }); + + connect(m_txtBrowser, &QTextBrowser::anchorClicked, [=](const QUrl& url) { + if (url.toString().startsWith(INTERNAL_URL_PASSATTACHMENT) && + m_root != nullptr && + m_root->getParentServiceRoot()->downloadAttachmentOnMyOwn(url)) { + return; + } + + if (!url.isEmpty()) { + bool open_externally_now = qApp->settings()->value(GROUP(Browser), + SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool(); + + if (open_externally_now) { + qApp->web()->openUrlInExternalBrowser(url.toString()); + } + else { + // User clicked some URL. Open it in external browser or download? + MessageBox box(qApp->mainFormWidget()); + box.setText(tr("You clicked some link. You can download the link contents or open it in external web browser.")); + box.setInformativeText(tr("What action do you want to take?")); + box.setDetailedText(url.toString()); + + QAbstractButton* btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ActionRole); + QAbstractButton* btn_download = box.addButton(tr("Download"), QMessageBox::ActionRole); + QAbstractButton* btn_cancel = box.addButton(QMessageBox::Cancel); + bool always; + MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always); + + box.setDefaultButton(QMessageBox::Cancel); + box.exec(); + + if (box.clickedButton() != box.button(QMessageBox::Cancel)) { + // Store selected checkbox value. + qApp->settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, always); + } + + if (box.clickedButton() == btn_open) { + qApp->web()->openUrlInExternalBrowser(url.toString()); + } + else if (box.clickedButton() == btn_download) { + qApp->downloadManager()->download(url); + } + + btn_download->deleteLater(); + btn_open->deleteLater(); + btn_cancel->deleteLater(); + } + } + else { + MessageBox::show(qApp->mainFormWidget(), QMessageBox::Warning, tr("Incorrect link"), tr("Selected hyperlink is invalid.")); + } + }); + connect(m_txtBrowser, + QOverload::of(&QTextBrowser::highlighted), + [=](const QUrl& url) { + Q_UNUSED(url) + QToolTip::showText(QCursor::pos(), tr("Click this link to download it or open it with external browser."), this); + }); + + m_searchWidget->hide(); + installEventFilter(this); +} + +void MessageBrowser::clear() { + m_txtBrowser->clear(); + m_pictures.clear(); + m_searchWidget->hide(); +} + +QString MessageBrowser::prepareHtmlForMessage(const Message& message) { + QString html = QString("

%1

").arg(message.m_title); + + if (!message.m_url.isEmpty()) { + html += QString("[url] %1
").arg(message.m_url); + } + + for (const Enclosure& enc : message.m_enclosures) { + QString enc_url; + + if (!enc.m_url.contains(QRegularExpression(QSL("^(http|ftp|\\/)")))) { + enc_url = QString(INTERNAL_URL_PASSATTACHMENT) + QL1S("/?") + enc.m_url; + } + else { + enc_url = enc.m_url; + } + + html += QString("[%2] %1
").arg(enc_url, enc.m_mimeType); + } + + QRegularExpression imgTagRegex("\\]*src\\s*=\\s*[\"\']([^\"\']*)[\"\'][^\\>]*\\>", + QRegularExpression::PatternOption::CaseInsensitiveOption | + QRegularExpression::PatternOption::InvertedGreedinessOption); + QRegularExpressionMatchIterator i = imgTagRegex.globalMatch(message.m_contents); + QString pictures_html; + + while (i.hasNext()) { + QRegularExpressionMatch match = i.next(); + + m_pictures.append(match.captured(1)); + pictures_html += QString("
[%1] %2").arg(tr("image"), match.captured(1)); + } + + if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayImagePlaceholders)).toBool()) { + html += message.m_contents; + } + else { + QString cnts = message.m_contents; + + html += cnts.replace(imgTagRegex, QString()); + } + + html += pictures_html; + html = html + .replace(QSL("\r\n"), QSL("\n")) + .replace(QL1C('\r'), QL1C('\n')) + .replace(QL1C('\n'), QSL("
")); + + return html; +} + +bool MessageBrowser::eventFilter(QObject* watched, QEvent* event) { + Q_UNUSED(watched) + + if (event->type() == QEvent::Type::KeyPress) { + auto* key_event = static_cast(event); + + if (key_event->matches(QKeySequence::StandardKey::Find)) { + + m_searchWidget->clear(); + m_searchWidget->show(); + m_searchWidget->setFocus(); + return true; + } + else if (key_event->key() == Qt::Key::Key_Escape) { + m_searchWidget->cancelSearch(); + return true; + } + } + + return false; +} + +void MessageBrowser::reloadFontSettings() { + const Settings* settings = qApp->settings(); + QFont fon; + + fon.fromString(settings->value(GROUP(Messages), SETTING(Messages::PreviewerFontStandard)).toString()); + setFont(fon); +} + +void MessageBrowser::loadMessage(const Message& message, RootItem* root) { + Q_UNUSED(root) + + m_txtBrowser->setHtml(prepareHtmlForMessage(message)); + m_txtBrowser->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum); + m_searchWidget->hide(); +} diff --git a/src/librssguard/gui/messagebrowser.h b/src/librssguard/gui/messagebrowser.h new file mode 100644 index 000000000..3db67f0db --- /dev/null +++ b/src/librssguard/gui/messagebrowser.h @@ -0,0 +1,44 @@ +// For license of this file, see /LICENSE.md. + +#ifndef MESSAGEBROWSER_H +#define MESSAGEBROWSER_H + +#include + +#include "core/message.h" + +#include "services/abstract/rootitem.h" + +#include + +class RootItem; +class QVBoxLayout; +class MessageTextBrowser; +class SearchTextWidget; + +class MessageBrowser : public QWidget { + Q_OBJECT + + public: + explicit MessageBrowser(QWidget* parent = nullptr); + + public slots: + void clear(); + void reloadFontSettings(); + void loadMessage(const Message& message, RootItem* root); + + protected: + bool eventFilter(QObject* watched, QEvent* event); + + private: + QString prepareHtmlForMessage(const Message& message); + + private: + MessageTextBrowser* m_txtBrowser; + SearchTextWidget* m_searchWidget; + QVBoxLayout* m_layout; + QStringList m_pictures; + QPointer m_root; +}; + +#endif // MESSAGEBROWSER_H diff --git a/src/librssguard/gui/messagepreviewer.cpp b/src/librssguard/gui/messagepreviewer.cpp index fad888b15..c41f9365e 100755 --- a/src/librssguard/gui/messagepreviewer.cpp +++ b/src/librssguard/gui/messagepreviewer.cpp @@ -13,7 +13,7 @@ #if defined (USE_WEBENGINE) #include "gui/webbrowser.h" #else -#include "gui/messagetextbrowser.h" +#include "gui/messagebrowser.h" #endif #include @@ -26,81 +26,6 @@ void MessagePreviewer::createConnections() { installEventFilter(this); -#if defined (USE_WEBENGINE) -#else - connect(m_searchWidget, &SearchTextWidget::cancelSearch, this, [this]() { - m_txtMessage->textCursor().clearSelection(); - m_txtMessage->moveCursor(QTextCursor::MoveOperation::Left); - }); - connect(m_searchWidget, &SearchTextWidget::searchForText, this, [this](const QString& text, bool backwards) { - if (backwards) { - m_txtMessage->find(text, QTextDocument::FindFlag::FindBackward); - } - else { - m_txtMessage->find(text); - } - }); - - connect(m_txtMessage, &QTextBrowser::anchorClicked, [=](const QUrl& url) { - if (url.toString().startsWith(INTERNAL_URL_PASSATTACHMENT) && - m_root != nullptr && - m_root->getParentServiceRoot()->downloadAttachmentOnMyOwn(url)) { - return; - } - - if (!url.isEmpty()) { - bool open_externally_now = qApp->settings()->value(GROUP(Browser), - SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool(); - - if (open_externally_now) { - qApp->web()->openUrlInExternalBrowser(url.toString()); - } - else { - // User clicked some URL. Open it in external browser or download? - MessageBox box(qApp->mainForm()); - box.setText(tr("You clicked some link. You can download the link contents or open it in external web browser.")); - box.setInformativeText(tr("What action do you want to take?")); - box.setDetailedText(url.toString()); - - QAbstractButton* btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ActionRole); - QAbstractButton* btn_download = box.addButton(tr("Download"), QMessageBox::ActionRole); - QAbstractButton* btn_cancel = box.addButton(QMessageBox::Cancel); - bool always; - MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always); - - box.setDefaultButton(QMessageBox::Cancel); - box.exec(); - - if (box.clickedButton() != box.button(QMessageBox::Cancel)) { - // Store selected checkbox value. - qApp->settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, always); - } - - if (box.clickedButton() == btn_open) { - qApp->web()->openUrlInExternalBrowser(url.toString()); - } - else if (box.clickedButton() == btn_download) { - qApp->downloadManager()->download(url); - } - - btn_download->deleteLater(); - btn_open->deleteLater(); - btn_cancel->deleteLater(); - } - } - else { - MessageBox::show(qApp->mainForm(), QMessageBox::Warning, tr("Incorrect link"), - tr("Selected hyperlink is invalid.")); - } - }); - connect(m_txtMessage, - QOverload::of(&QTextBrowser::highlighted), - [=](const QUrl& url) { - Q_UNUSED(url) - QToolTip::showText(QCursor::pos(), tr("Click this link to download it or open it with external browser."), this); - }); -#endif - connect(m_actionMarkRead = m_toolBar->addAction(qApp->icons()->fromTheme("mail-mark-read"), tr("Mark message as read")), &QAction::triggered, this, @@ -120,27 +45,17 @@ MessagePreviewer::MessagePreviewer(QWidget* parent) #if defined (USE_WEBENGINE) m_txtMessage = new WebBrowser(this); #else - m_txtMessage = new MessageTextBrowser(this); - m_searchWidget = new SearchTextWidget(this); + m_txtMessage = new MessageBrowser(this); #endif m_toolBar->setOrientation(Qt::Vertical); m_layout->setContentsMargins(3, 3, 3, 3); m_layout->addWidget(m_txtMessage, 0, 1, 1, 1); - -#if !defined (USE_WEBENGINE) - m_layout->addWidget(m_searchWidget, 1, 1, 1, 1); -#endif - m_layout->addWidget(m_toolBar, 0, 0, -1, 1); createConnections(); m_actionSwitchImportance->setCheckable(true); -#if defined (USE_WEBENGINE) -#else - m_searchWidget->hide(); -#endif reloadFontSettings(); clear(); } @@ -175,11 +90,6 @@ void MessagePreviewer::loadMessage(const Message& message, RootItem* root) { show(); m_actionSwitchImportance->setChecked(m_message.m_isImportant); m_txtMessage->loadMessage(message, root); - -#if !defined (USE_WEBENGINE) - m_searchWidget->hide(); - m_txtMessage->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum); -#endif } } @@ -236,26 +146,6 @@ void MessagePreviewer::switchMessageImportance(bool checked) { } } -bool MessagePreviewer::eventFilter(QObject* watched, QEvent* event) { - Q_UNUSED(watched) - -#if !defined (USE_WEBENGINE) - if (event->type() == QEvent::Type::KeyPress) { - auto* key_event = static_cast(event); - - if (key_event->matches(QKeySequence::StandardKey::Find)) { - - m_searchWidget->clear(); - m_searchWidget->show(); - m_searchWidget->setFocus(); - return true; - } - } -#endif - - return false; -} - void MessagePreviewer::updateButtons() { m_actionMarkRead->setEnabled(!m_message.m_isRead); m_actionMarkUnread->setEnabled(m_message.m_isRead); diff --git a/src/librssguard/gui/messagepreviewer.h b/src/librssguard/gui/messagepreviewer.h index b6e887c0b..f674b2c2a 100644 --- a/src/librssguard/gui/messagepreviewer.h +++ b/src/librssguard/gui/messagepreviewer.h @@ -16,8 +16,7 @@ class QToolBar; #if defined (USE_WEBENGINE) class WebBrowser; #else -class MessageTextBrowser; -class SearchTextWidget; +class MessageBrowser; #endif class MessagePreviewer : public QWidget { @@ -44,7 +43,6 @@ class MessagePreviewer : public QWidget { void switchMessageImportance(bool checked); protected: - bool eventFilter(QObject* watched, QEvent* event); signals: void markMessageRead(int id, RootItem::ReadStatus read); @@ -60,8 +58,7 @@ class MessagePreviewer : public QWidget { #if defined (USE_WEBENGINE) WebBrowser* m_txtMessage; #else - MessageTextBrowser* m_txtMessage; - SearchTextWidget* m_searchWidget; + MessageBrowser* m_txtMessage; #endif Message m_message; diff --git a/src/librssguard/gui/messagetextbrowser.cpp b/src/librssguard/gui/messagetextbrowser.cpp index 6c3ef4602..4083626f4 100644 --- a/src/librssguard/gui/messagetextbrowser.cpp +++ b/src/librssguard/gui/messagetextbrowser.cpp @@ -5,7 +5,6 @@ #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "network-web/networkfactory.h" -#include "services/abstract/rootitem.h" MessageTextBrowser::MessageTextBrowser(QWidget* parent) : QTextBrowser(parent) { setAutoFillBackground(true); @@ -16,57 +15,6 @@ MessageTextBrowser::MessageTextBrowser(QWidget* parent) : QTextBrowser(parent) { viewport()->setAutoFillBackground(true); } -QString MessageTextBrowser::prepareHtmlForMessage(const Message& message) { - QString html = QString("

%1

").arg(message.m_title); - - if (!message.m_url.isEmpty()) { - html += QString("[url] %1
").arg(message.m_url); - } - - for (const Enclosure& enc : message.m_enclosures) { - QString enc_url; - - if (!enc.m_url.contains(QRegularExpression(QSL("^(http|ftp|\\/)")))) { - enc_url = QString(INTERNAL_URL_PASSATTACHMENT) + QL1S("/?") + enc.m_url; - } - else { - enc_url = enc.m_url; - } - - html += QString("[%2] %1
").arg(enc_url, enc.m_mimeType); - } - - QRegularExpression imgTagRegex("\\]*src\\s*=\\s*[\"\']([^\"\']*)[\"\'][^\\>]*\\>", - QRegularExpression::PatternOption::CaseInsensitiveOption | - QRegularExpression::PatternOption::InvertedGreedinessOption); - QRegularExpressionMatchIterator i = imgTagRegex.globalMatch(message.m_contents); - QString pictures_html; - - while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); - - m_pictures.append(match.captured(1)); - pictures_html += QString("
[%1] %2").arg(tr("image"), match.captured(1)); - } - - if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayImagePlaceholders)).toBool()) { - html += message.m_contents; - } - else { - QString cnts = message.m_contents; - - html += cnts.replace(imgTagRegex, QString()); - } - - html += pictures_html; - html = html - .replace(QSL("\r\n"), QSL("\n")) - .replace(QL1C('\r'), QL1C('\n')) - .replace(QL1C('\n'), QSL("
")); - - return html; -} - QVariant MessageTextBrowser::loadResource(int type, const QUrl& name) { Q_UNUSED(name) @@ -89,25 +37,6 @@ QVariant MessageTextBrowser::loadResource(int type, const QUrl& name) { } } -void MessageTextBrowser::clear() { - QTextBrowser::clear(); - m_pictures.clear(); -} - -void MessageTextBrowser::reloadFontSettings() { - const Settings* settings = qApp->settings(); - QFont fon; - - fon.fromString(settings->value(GROUP(Messages), SETTING(Messages::PreviewerFontStandard)).toString()); - setFont(fon); -} - -void MessageTextBrowser::loadMessage(const Message& message, RootItem* root) { - Q_UNUSED(root) - - setHtml(prepareHtmlForMessage(message)); -} - void MessageTextBrowser::wheelEvent(QWheelEvent* e) { QTextBrowser::wheelEvent(e); qApp->settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, font().toString()); diff --git a/src/librssguard/gui/messagetextbrowser.h b/src/librssguard/gui/messagetextbrowser.h index a0487d09c..64688813f 100644 --- a/src/librssguard/gui/messagetextbrowser.h +++ b/src/librssguard/gui/messagetextbrowser.h @@ -7,8 +7,6 @@ #include "core/message.h" -class RootItem; - class MessageTextBrowser : public QTextBrowser { Q_OBJECT @@ -18,20 +16,11 @@ class MessageTextBrowser : public QTextBrowser { QVariant loadResource(int type, const QUrl& name); - public slots: - void clear(); - void reloadFontSettings(); - void loadMessage(const Message& message, RootItem* root); - protected: void wheelEvent(QWheelEvent* e); - private: - QString prepareHtmlForMessage(const Message& message); - private: QPixmap m_imagePlaceholder; - QStringList m_pictures; }; #endif // MESSAGETEXTBROWSER_H diff --git a/src/librssguard/gui/searchtextwidget.cpp b/src/librssguard/gui/searchtextwidget.cpp index db8143609..da1fd87ab 100644 --- a/src/librssguard/gui/searchtextwidget.cpp +++ b/src/librssguard/gui/searchtextwidget.cpp @@ -33,6 +33,12 @@ void SearchTextWidget::clear() { m_ui.m_txtSearch->clear(); } +void SearchTextWidget::cancelSearch() { + emit searchCancelled(); + + hide(); +} + void SearchTextWidget::onTextChanged(const QString& text) { m_ui.m_btnSearchBackward->setDisabled(text.isEmpty()); m_ui.m_btnSearchForward->setDisabled(text.isEmpty()); @@ -42,15 +48,13 @@ void SearchTextWidget::onTextChanged(const QString& text) { emit searchForText(text, false); } else { - emit cancelSearch(); + emit searchCancelled(); } } void SearchTextWidget::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key::Key_Escape) { - emit cancelSearch(); - - hide(); + cancelSearch(); } } diff --git a/src/librssguard/gui/searchtextwidget.h b/src/librssguard/gui/searchtextwidget.h index dd2309552..b5a8d0c3a 100644 --- a/src/librssguard/gui/searchtextwidget.h +++ b/src/librssguard/gui/searchtextwidget.h @@ -19,6 +19,7 @@ class SearchTextWidget : public QWidget { public slots: void clear(); + void cancelSearch(); private slots: void onTextChanged(const QString& text); @@ -29,7 +30,7 @@ class SearchTextWidget : public QWidget { signals: void searchForText(QString text, bool search_backwards); - void cancelSearch(); + void searchCancelled(); private: Ui::SearchTextWidget m_ui; diff --git a/src/librssguard/gui/webbrowser.cpp b/src/librssguard/gui/webbrowser.cpp index baa668370..a6cb52a49 100644 --- a/src/librssguard/gui/webbrowser.cpp +++ b/src/librssguard/gui/webbrowser.cpp @@ -43,7 +43,7 @@ WebBrowser::WebBrowser(QWidget* parent) : TabContent(parent), void WebBrowser::createConnections() { installEventFilter(this); - connect(m_searchWidget, &SearchTextWidget::cancelSearch, this, [this]() { + connect(m_searchWidget, &SearchTextWidget::searchCancelled, this, [this]() { m_webView->findText(QString()); }); connect(m_searchWidget, &SearchTextWidget::searchForText, this, [this](const QString& text, bool backwards) { diff --git a/src/librssguard/gui/webbrowser.h b/src/librssguard/gui/webbrowser.h index 7f8d9d52a..7d5395579 100644 --- a/src/librssguard/gui/webbrowser.h +++ b/src/librssguard/gui/webbrowser.h @@ -34,9 +34,9 @@ class WebBrowser : public TabContent { WebBrowser* webBrowser() const; WebViewer* viewer() const; + public slots: void reloadFontSettings(); - public slots: void increaseZoom(); void decreaseZoom(); void resetZoom(); diff --git a/src/librssguard/librssguard.pro b/src/librssguard/librssguard.pro index 9a6c80d04..d61c3ea8d 100644 --- a/src/librssguard/librssguard.pro +++ b/src/librssguard/librssguard.pro @@ -404,8 +404,10 @@ equals(USE_WEBENGINE, true) { network-web/adblock/adblockdialog.ui } else { - HEADERS += gui/messagetextbrowser.h - SOURCES += gui/messagetextbrowser.cpp + HEADERS += gui/messagetextbrowser.h \ + gui/messagebrowser.h + SOURCES += gui/messagetextbrowser.cpp \ + gui/messagebrowser.cpp } # Add mimesis.