Refactor non-webengine too.

This commit is contained in:
Martin Rotter 2020-09-15 13:55:50 +02:00
parent 51401376be
commit 8e1c2d94d7
11 changed files with 258 additions and 208 deletions

View File

@ -0,0 +1,194 @@
// For license of this file, see <project-root-folder>/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 <QKeyEvent>
#include <QRegularExpression>
#include <QScrollBar>
#include <QToolTip>
#include <QVBoxLayout>
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<const QUrl&>::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("<h2 align=\"center\">%1</h2>").arg(message.m_title);
if (!message.m_url.isEmpty()) {
html += QString("[url] <a href=\"%1\">%1</a><br/>").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] <a href=\"%1\">%1</a><br/>").arg(enc_url, enc.m_mimeType);
}
QRegularExpression imgTagRegex("\\<img[^\\>]*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("<br/>[%1] <a href=\"%2\">%2</a>").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("<br/>"));
return html;
}
bool MessageBrowser::eventFilter(QObject* watched, QEvent* event) {
Q_UNUSED(watched)
if (event->type() == QEvent::Type::KeyPress) {
auto* key_event = static_cast<QKeyEvent*>(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();
}

View File

@ -0,0 +1,44 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#ifndef MESSAGEBROWSER_H
#define MESSAGEBROWSER_H
#include <QWidget>
#include "core/message.h"
#include "services/abstract/rootitem.h"
#include <QPointer>
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<RootItem> m_root;
};
#endif // MESSAGEBROWSER_H

View File

@ -13,7 +13,7 @@
#if defined (USE_WEBENGINE)
#include "gui/webbrowser.h"
#else
#include "gui/messagetextbrowser.h"
#include "gui/messagebrowser.h"
#endif
#include <QGridLayout>
@ -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<const QUrl&>::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<QKeyEvent*>(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);

View File

@ -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;

View File

@ -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("<h2 align=\"center\">%1</h2>").arg(message.m_title);
if (!message.m_url.isEmpty()) {
html += QString("[url] <a href=\"%1\">%1</a><br/>").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] <a href=\"%1\">%1</a><br/>").arg(enc_url, enc.m_mimeType);
}
QRegularExpression imgTagRegex("\\<img[^\\>]*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("<br/>[%1] <a href=\"%2\">%2</a>").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("<br/>"));
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());

View File

@ -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

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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) {

View File

@ -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();

View File

@ -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.