Commit 00232c2d authored by Volker Krause's avatar Volker Krause

Port internal render plugins to HtmlWriter

Summary:
The next steps are using streaming API also for the nested Grantlee
invocations and replacing DefaultRendererPrivate* in the render plugin
API.

Reviewers: knauss

Reviewed By: knauss

Subscribers: #kde_pim

Tags: #kde_pim

Differential Revision: https://phabricator.kde.org/D8102
parent 4886691e
......@@ -160,7 +160,6 @@ set(libmessageviewer_messagepartthemes_default_SRCS
messagepartthemes/default/defaultrenderer.cpp
messagepartthemes/default/htmlblock.cpp
messagepartthemes/default/messagepartrenderermanager.cpp
messagepartthemes/default/partrendered.cpp
messagepartthemes/default/plugins/attachmentmessagepartrenderer.cpp
messagepartthemes/default/plugins/messagepartrenderer.cpp
messagepartthemes/default/plugins/textmessagepartrenderer.cpp
......
......@@ -28,7 +28,6 @@
#include "messagepartrendererbase.h"
#include "messagepartrendererfactory.h"
#include "htmlblock.h"
#include "partrendered.h"
#include "utils/iconnamecache.h"
#include "utils/mimetype.h"
......@@ -472,9 +471,9 @@ void DefaultRendererPrivate::renderEncrypted(const EncryptedMessagePart::Ptr &mp
}
c.insert(QStringLiteral("content"), _htmlWriter->html());
} else if (!metaData.inProgress) {
auto part = renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp);
if (part) {
c.insert(QStringLiteral("content"), part->html());
CacheHtmlWriter nestedWriter(htmlWriter);
if (renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp, &nestedWriter)) {
c.insert(QStringLiteral("content"), nestedWriter.html());
} else {
c.insert(QStringLiteral("content"), QString());
}
......@@ -528,9 +527,9 @@ void DefaultRendererPrivate::renderSigned(const SignedMessagePart::Ptr &mp, Html
}
c.insert(QStringLiteral("content"), _htmlWriter->html());
} else if (!metaData.inProgress) {
auto part = renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp);
if (part) {
c.insert(QStringLiteral("content"), part->html());
CacheHtmlWriter nestedWriter(htmlWriter);
if (renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp, &nestedWriter)) {
c.insert(QStringLiteral("content"), nestedWriter.html());
} else {
c.insert(QStringLiteral("content"), QString());
}
......@@ -770,10 +769,7 @@ void DefaultRendererPrivate::render(const SignedMessagePart::Ptr &mp, HtmlWriter
if (mp->hasSubParts()) {
renderSubParts(mp, htmlWriter);
} else if (!metaData.inProgress) {
auto part = renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp);
if (part) {
htmlWriter->write(part->html());
}
renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp, htmlWriter);
}
}
......@@ -798,10 +794,7 @@ void DefaultRendererPrivate::render(const EncryptedMessagePart::Ptr &mp, HtmlWri
if (mp->hasSubParts()) {
renderSubParts(mp, htmlWriter);
} else if (!metaData.inProgress) {
auto part = renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp);
if (part) {
htmlWriter->write(part->html());
}
renderWithFactory(QStringLiteral("MimeTreeParser::MessagePart"), mp, htmlWriter);
}
}
......@@ -864,39 +857,26 @@ void DefaultRendererPrivate::render(const CertMessagePart::Ptr &mp, HtmlWriter *
t->render(&s, &c);
}
QSharedPointer<PartRendered> DefaultRendererPrivate::renderWithFactory(QString className, const MessagePart::Ptr &msgPart)
bool DefaultRendererPrivate::renderWithFactory(const QString &className, const MessagePart::Ptr &msgPart, HtmlWriter *htmlWriter)
{
if (mRendererFactory) {
const auto registry = mRendererFactory->typeRegistry(className);
if (registry.size() > 0) {
const auto plugin = registry.at(0);
return plugin->render(this, msgPart);
}
}
return QSharedPointer<PartRendered>();
if (!mRendererFactory)
return false;
const auto registry = mRendererFactory->typeRegistry(className);
if (registry.empty())
return false;
const auto plugin = registry.at(0);
return plugin->render(this, msgPart, htmlWriter);
}
QString DefaultRendererPrivate::renderFactory(const MessagePart::Ptr &msgPart, HtmlWriter *_htmlWriter)
{
auto htmlWriter = QSharedPointer<CacheHtmlWriter>(new CacheHtmlWriter(mOldWriter));
const QString className = QString::fromUtf8(msgPart->metaObject()->className());
const auto rendered = renderWithFactory(className, msgPart);
if (rendered) {
const auto parts = rendered->embededParts();
foreach (auto key, parts.keys()) {
_htmlWriter->embedPart(key, parts.value(key));
}
foreach (auto entry, rendered->extraHeader()) {
_htmlWriter->extraHead(entry);
}
if (renderWithFactory(className, msgPart, htmlWriter.data()))
return htmlWriter->html();
return rendered->html();
}
auto htmlWriter = QSharedPointer<CacheHtmlWriter>(new CacheHtmlWriter(mOldWriter));
if (className == QStringLiteral("MimeTreeParser::MessagePartList")) {
auto mp = msgPart.dynamicCast<MessagePartList>();
if (mp) {
......
......@@ -58,7 +58,7 @@ public:
void render(const EncryptedMessagePart::Ptr &mp, HtmlWriter *htmlWriter);
void render(const AlternativeMessagePart::Ptr &mp, HtmlWriter *htmlWriter);
void render(const CertMessagePart::Ptr &mp, HtmlWriter *htmlWriter);
QSharedPointer<PartRendered> renderWithFactory(QString className, const MessagePart::Ptr &msgPart);
bool renderWithFactory(const QString &className, const MessagePart::Ptr &msgPart, HtmlWriter *writer);
QString renderFactory(const MessagePart::Ptr &msgPart, HtmlWriter *htmlWriter);
QString mHtml;
......
......@@ -39,18 +39,17 @@
namespace MimeTreeParser {
class DefaultRendererPrivate;
class HtmlWriter;
class MessagePart;
typedef QSharedPointer<MessagePart> MessagePartPtr;
}
class PartRendered;
class MessagePartRendererBase
{
public:
MessagePartRendererBase();
virtual ~MessagePartRendererBase();
virtual QSharedPointer<PartRendered> render(MimeTreeParser::DefaultRendererPrivate *, const MimeTreeParser::MessagePartPtr &)
virtual bool render(MimeTreeParser::DefaultRendererPrivate *, const MimeTreeParser::MessagePartPtr &, MimeTreeParser::HtmlWriter *htmlWriter)
const = 0;
};
#endif
/*
Copyright (c) 2017 Sandro Knauß <sknauss@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#include "partrendered.h"
#include "defaultrenderer.h"
#include "defaultrenderer_p.h"
#include "htmlblock.h"
#include "messagepartrenderermanager.h"
#include <MimeTreeParser/BufferedHtmlWriter>
#include <MimeTreeParser/MessagePart>
#include <MessageCore/StringUtil>
#include <grantlee/context.h>
#include <grantlee/template.h>
#include <QApplication>
using namespace MessageViewer;
PartRendered::PartRendered()
{
}
PartRendered::~PartRendered()
{
}
inline QString PartRendered::alignText()
{
return QApplication::isRightToLeft() ? QStringLiteral("rtl") : QStringLiteral("ltr");
}
QVector<QSharedPointer<PartRendered> > PartRendered::renderSubParts(
MimeTreeParser::MessagePart::Ptr mp)
{
QVector<QSharedPointer<PartRendered> > ret;
foreach (const auto &_m, mp->subParts()) {
CacheHtmlWriter cacheWriter;
DefaultRenderer::Ptr renderer = mp->source()->messagePartTheme(_m);
cacheWriter.write(renderer->html());
ret.append(QSharedPointer<WrapperPartRendered>(new WrapperPartRendered(&cacheWriter)));
}
return ret;
}
EmptyPartRendered::EmptyPartRendered()
{
}
EmptyPartRendered::~EmptyPartRendered()
{
}
QString EmptyPartRendered::extraHeader()
{
return QString();
}
QString EmptyPartRendered::html()
{
return QString();
}
QMap<QByteArray, QString> EmptyPartRendered::embededParts()
{
return QMap<QByteArray, QString>();
}
WrapperPartRendered::WrapperPartRendered(CacheHtmlWriter *htmlWriter)
: PartRendered()
{
mHtml = htmlWriter->html();
mHead = htmlWriter->head;
mEmbeded = htmlWriter->embedParts;
}
WrapperPartRendered::~WrapperPartRendered()
{
}
QString WrapperPartRendered::html()
{
return mHtml;
}
QString WrapperPartRendered::extraHeader()
{
return mHead;
}
QMap<QByteArray, QString> WrapperPartRendered::embededParts()
{
return mEmbeded;
}
HtmlOnlyPartRendered::HtmlOnlyPartRendered(MimeTreeParser::MessagePart::Ptr mp, const QString &html)
: mHtml(html)
{
mShowAttachmentBlock = mp->isAttachment();
mAttachmentNode = mp->attachmentContent();
}
HtmlOnlyPartRendered::~HtmlOnlyPartRendered()
{
}
QMap<QByteArray, QString> HtmlOnlyPartRendered::embededParts()
{
return QMap<QByteArray, QString>();
}
QString HtmlOnlyPartRendered::extraHeader()
{
return QString();
}
QString HtmlOnlyPartRendered::html()
{
MimeTreeParser::AttachmentMarkBlock block(nullptr, mAttachmentNode);
QString ret;
if (mShowAttachmentBlock) {
ret += block.enter();
}
ret += mHtml;
ret += block.exit();
return ret;
}
TextPartRendered::TextPartRendered(MimeTreeParser::TextMessagePart::Ptr mp)
: mShowAttachmentBlock(false)
, mAttachmentNode(nullptr)
{
auto node = mp->content();
auto nodeHelper = mp->mOtp->nodeHelper();
if (mp->isHidden()) {
return;
}
Grantlee::Template t;
Grantlee::Context c = MessageViewer::MessagePartRendererManager::self()->createContext();
QObject block;
c.insert(QStringLiteral("block"), &block);
block.setProperty("showTextFrame", mp->showTextFrame());
block.setProperty("label",
MessageCore::StringUtil::quoteHtmlChars(MimeTreeParser::NodeHelper::fileName(
node), true));
block.setProperty("comment",
MessageCore::StringUtil::quoteHtmlChars(node->contentDescription()->
asUnicodeString(), true));
block.setProperty("link", nodeHelper->asHREF(node, QStringLiteral("body")));
block.setProperty("showLink", mp->showLink());
block.setProperty("dir", alignText());
t
= MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(
":/textmessagepart.html"));
mSubList = renderSubParts(mp);
QString content;
foreach (auto part, mSubList) {
content += part->html();
}
c.insert(QStringLiteral("content"), content);
mShowAttachmentBlock = mp->isAttachment();
mHtml = t->render(&c);
mAttachmentNode = mp->attachmentContent();
}
TextPartRendered::~TextPartRendered()
{
}
QMap<QByteArray, QString> TextPartRendered::embededParts()
{
QMap<QByteArray, QString> ret;
foreach (auto part, mSubList) {
//ret += part->embededParts();
}
return ret;
}
QString TextPartRendered::extraHeader()
{
QString ret;
foreach (auto part, mSubList) {
ret += part->extraHeader();
}
return ret;
}
QString TextPartRendered::html()
{
MimeTreeParser::AttachmentMarkBlock block(nullptr, mAttachmentNode);
QString ret;
if (mShowAttachmentBlock) {
ret += block.enter();
}
ret += mHtml;
ret += block.exit();
return ret;
}
/*
Copyright (c) 2017 Sandro Knauß <sknauss@kde.org>
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef __MESSAGEVIEWER_PARTRENDERED_H__
#define __MESSAGEVIEWER_PARTRENDERED_H__
#include "cachehtmlwriter.h"
#include <QMap>
#include <QString>
#include <QSharedPointer>
#include <QVector>
namespace MimeTreeParser {
class MessagePart;
typedef QSharedPointer<MessagePart> MessagePartPtr;
class TextMessagePart;
typedef QSharedPointer<TextMessagePart> TextMessagePartPtr;
class DefaultRendererPrivate;
}
namespace KMime {
class Content;
}
class PartRendered
{
public:
PartRendered();
virtual ~PartRendered();
inline QString alignText();
virtual QString html() = 0;
virtual QMap<QByteArray, QString> embededParts() = 0;
virtual QString extraHeader() = 0;
protected:
QVector<QSharedPointer<PartRendered> > renderSubParts(MimeTreeParser::MessagePartPtr mp);
};
class EmptyPartRendered : public PartRendered
{
public:
EmptyPartRendered();
virtual ~EmptyPartRendered();
QString html() override;
QMap<QByteArray, QString> embededParts() override;
QString extraHeader() override;
};
class WrapperPartRendered : public PartRendered
{
public:
WrapperPartRendered(MessageViewer::CacheHtmlWriter*);
virtual ~WrapperPartRendered();
QString html() override;
QMap<QByteArray, QString> embededParts() override;
QString extraHeader() override;
private:
QString mHtml;
QString mHead;
QMap<QByteArray, QString> mEmbeded;
};
class HtmlOnlyPartRendered : public PartRendered
{
public:
HtmlOnlyPartRendered(MimeTreeParser::MessagePartPtr part, const QString &html);
virtual ~HtmlOnlyPartRendered();
QString html() override;
QMap<QByteArray, QString> embededParts() override;
QString extraHeader() override;
protected:
void setHtml(const QString &html);
private:
QString mHtml;
bool mShowAttachmentBlock;
KMime::Content *mAttachmentNode = nullptr;
};
class TextPartRendered : public PartRendered
{
public:
TextPartRendered(MimeTreeParser::TextMessagePartPtr part);
virtual ~TextPartRendered();
QString html() override;
QMap<QByteArray, QString> embededParts() override;
QString extraHeader() override;
private:
QString mHtml;
QVector<QSharedPointer<PartRendered> > mSubList;
bool mShowAttachmentBlock;
KMime::Content *mAttachmentNode = nullptr;
};
#endif
......@@ -22,11 +22,12 @@
#include "quotehtml.h"
#include "utils/mimetype.h"
#include "../partrendered.h"
#include "../htmlblock.h"
#include "../defaultrenderer_p.h"
#include "../messagepartrenderermanager.h"
#include <MessageCore/StringUtil>
#include <MimeTreeParser/HtmlWriter>
#include <KIconLoader>
#include <KLocalizedString>
......@@ -40,25 +41,24 @@ AttachmentMessagePartRenderer::~AttachmentMessagePartRenderer()
{
}
QSharedPointer<PartRendered> AttachmentMessagePartRenderer::render(DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart)
const
bool AttachmentMessagePartRenderer::render(MimeTreeParser::DefaultRendererPrivate* drp, const MimeTreeParser::MessagePartPtr& msgPart, MimeTreeParser::HtmlWriter* htmlWriter) const
{
auto mp = msgPart.dynamicCast<AttachmentMessagePart>();
if (!mp) {
return QSharedPointer<PartRendered>();
return false;
}
KMime::Content *node = mp->content();
NodeHelper *nodeHelper = mp->mOtp->nodeHelper();
if (mp->isHidden()) {
return QSharedPointer<PartRendered>(new EmptyPartRendered());
return true;
}
const auto tmpAsIcon = mp->asIcon();
if (tmpAsIcon == MimeTreeParser::NoIcon) {
return drp->renderWithFactory(QStringLiteral("MimeTreeParser::TextMessagePart"), mp);
return drp->renderWithFactory(QStringLiteral("MimeTreeParser::TextMessagePart"), mp, htmlWriter);
}
Grantlee::Template t = MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(
......@@ -109,6 +109,13 @@ const
block.setProperty("label", label);
block.setProperty("comment", comment);
const auto html = t->render(&c);
return QSharedPointer<PartRendered>(new HtmlOnlyPartRendered(mp, html));
MimeTreeParser::AttachmentMarkBlock attBlock(nullptr, mp->attachmentContent());
if (mp->isAttachment())
htmlWriter->write(attBlock.enter());
Grantlee::OutputStream s(htmlWriter->stream());
t->render(&s, &c);
htmlWriter->write(attBlock.exit());
return true;
}
......@@ -29,8 +29,7 @@ class AttachmentMessagePartRenderer : public MessagePartRendererBase
public:
AttachmentMessagePartRenderer();
virtual ~AttachmentMessagePartRenderer();
QSharedPointer<PartRendered> render(MimeTreeParser::DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart)
const override;
bool render(MimeTreeParser::DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) const override;
};
#endif
......@@ -21,9 +21,11 @@
#include "quotehtml.h"
#include "../partrendered.h"
#include "../htmlblock.h"
#include "../defaultrenderer_p.h"
#include <MimeTreeParser/HtmlWriter>
MessagePartRenderer::MessagePartRenderer()
{
}
......@@ -32,10 +34,14 @@ MessagePartRenderer::~MessagePartRenderer()
{
}
QSharedPointer<PartRendered> MessagePartRenderer::render(
MimeTreeParser::DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart) const
bool MessagePartRenderer::render(MimeTreeParser::DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) const
{
return QSharedPointer<PartRendered>(new HtmlOnlyPartRendered(msgPart, quotedHTML(msgPart->text(),
msgPart->source(),
drp->cssHelper())));
MimeTreeParser::AttachmentMarkBlock block(nullptr, msgPart->attachmentContent());
if (msgPart->isAttachment()) {
htmlWriter->write(block.enter());
}
htmlWriter->write(quotedHTML(msgPart->text(), msgPart->source(), drp->cssHelper()));
htmlWriter->write(block.exit());
return true;
}
......@@ -29,8 +29,7 @@ class MessagePartRenderer : public MessagePartRendererBase
public:
MessagePartRenderer();
virtual ~MessagePartRenderer();
QSharedPointer<PartRendered> render(MimeTreeParser::DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart)
const override;
bool render(MimeTreeParser::DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart, MimeTreeParser::HtmlWriter *htmlWriter) const override;
};
#endif
......@@ -21,8 +21,17 @@
#include "quotehtml.h"
#include "../partrendered.h"
#include "../defaultrenderer_p.h"
#include "../htmlblock.h"
#include "../messagepartrenderermanager.h"
#include <MessageCore/StringUtil>
#include <MimeTreeParser/HtmlWriter>
#include <grantlee/context.h>
#include <grantlee/template.h>
#include <QApplication>
TextMessagePartRenderer::TextMessagePartRenderer()
{
......@@ -32,12 +41,55 @@ TextMessagePartRenderer::~TextMessagePartRenderer()
{
}
QSharedPointer<PartRendered> TextMessagePartRenderer::render(DefaultRendererPrivate *drp, const MimeTreeParser::MessagePartPtr &msgPart)
const
static QString alignText()
{
return QApplication::isRightToLeft() ? QStringLiteral("rtl") : QStringLiteral("ltr");
}
bool TextMessagePartRenderer::render(MimeTreeParser::DefaultRendererPrivate* drp, const MimeTreeParser::MessagePartPtr& msgPart, MimeTreeParser::HtmlWriter* htmlWriter) const
{
auto mp = msgPart.dynamicCast<TextMessagePart>();
if (mp) {
return QSharedPointer<PartRendered>(new TextPartRendered(mp));
if (!mp)