7 #include "defaultrenderer.h"
9 #include "defaultrenderer_p.h"
11 #include "utils/messageviewerutil.h"
13 #include "messageviewer_debug.h"
15 #include "converthtmltoplaintext.h"
16 #include "htmlblock.h"
17 #include "messagepartrendererbase.h"
18 #include "messagepartrendererfactory.h"
19 #include "messagepartrenderermanager.h"
20 #include "utils/iconnamecache.h"
21 #include "utils/mimetype.h"
22 #include "viewer/attachmentstrategy.h"
23 #include "viewer/csshelperbase.h"
25 #include "htmlwriter/bufferedhtmlwriter.h"
26 #include <MimeTreeParser/MessagePart>
27 #include <MimeTreeParser/ObjectTreeParser>
29 #include <QGpgME/Protocol>
31 #include <MessageCore/StringUtil>
33 #include <KEmailAddress>
34 #include <KIconLoader>
35 #include <KLocalizedString>
38 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
39 #include <grantlee/context.h>
40 #include <grantlee/engine.h>
41 #include <grantlee/metatype.h>
42 #include <grantlee/template.h>
43 #include <grantlee/templateloader.h>
45 #include <KTextTemplate/context.h>
46 #include <KTextTemplate/engine.h>
47 #include <KTextTemplate/metatype.h>
48 #include <KTextTemplate/template.h>
49 #include <KTextTemplate/templateloader.h>
52 using namespace MimeTreeParser;
53 using namespace MessageViewer;
54 #ifndef COMPILE_WITH_UNITY_CMAKE_SUPPORT
55 Q_DECLARE_METATYPE(GpgME::DecryptionResult::Recipient)
56 Q_DECLARE_METATYPE(GpgME::Key)
57 Q_DECLARE_METATYPE(
const QGpgME::Protocol *)
59 static const int SIG_FRAME_COL_UNDEF = 99;
60 #define SIG_FRAME_COL_RED -1
61 #define SIG_FRAME_COL_YELLOW 0
62 #define SIG_FRAME_COL_GREEN 1
63 QString sigStatusToString(
const QGpgME::Protocol *cryptProto,
int status_code, GpgME::Signature::Summary summary,
int &frameColor,
bool &showKeyInfos)
71 if (cryptProto == QGpgME::openpgp()) {
74 switch (status_code) {
76 result =
i18n(
"Error: Signature not verified");
77 frameColor = SIG_FRAME_COL_YELLOW;
80 result =
i18n(
"Good signature");
81 frameColor = SIG_FRAME_COL_GREEN;
84 result =
i18n(
"Bad signature");
85 frameColor = SIG_FRAME_COL_RED;
88 result =
i18n(
"No public key to verify the signature");
89 frameColor = SIG_FRAME_COL_RED;
92 result =
i18n(
"No signature found");
93 frameColor = SIG_FRAME_COL_RED;
96 result =
i18n(
"Error verifying the signature");
97 frameColor = SIG_FRAME_COL_RED;
100 result =
i18n(
"Different results for signatures");
101 frameColor = SIG_FRAME_COL_RED;
115 }
else if (cryptProto == QGpgME::smime()) {
119 if (summary == GpgME::Signature::None) {
120 result =
i18n(
"No status information available.");
121 frameColor = SIG_FRAME_COL_YELLOW;
122 showKeyInfos =
false;
126 if (summary & GpgME::Signature::Valid) {
127 result =
i18n(
"Good signature.");
136 frameColor = SIG_FRAME_COL_GREEN;
137 showKeyInfos =
false;
144 frameColor = SIG_FRAME_COL_GREEN;
146 if (summary & GpgME::Signature::KeyExpired) {
148 result2 =
i18n(
"One key has expired.");
150 if (summary & GpgME::Signature::SigExpired) {
152 result2 +=
i18n(
"The signature has expired.");
156 if (summary & GpgME::Signature::KeyMissing) {
157 result2 +=
i18n(
"Unable to verify: key missing.");
160 showKeyInfos =
false;
161 frameColor = SIG_FRAME_COL_YELLOW;
163 if (summary & GpgME::Signature::CrlMissing) {
164 result2 +=
i18n(
"CRL not available.");
165 frameColor = SIG_FRAME_COL_YELLOW;
167 if (summary & GpgME::Signature::CrlTooOld) {
168 result2 +=
i18n(
"Available CRL is too old.");
169 frameColor = SIG_FRAME_COL_YELLOW;
171 if (summary & GpgME::Signature::BadPolicy) {
172 result2 +=
i18n(
"A policy was not met.");
173 frameColor = SIG_FRAME_COL_YELLOW;
175 if (summary & GpgME::Signature::SysError) {
176 result2 +=
i18n(
"A system error occurred.");
180 showKeyInfos =
false;
181 frameColor = SIG_FRAME_COL_YELLOW;
185 if (summary & GpgME::Signature::KeyRevoked) {
187 result2 +=
i18n(
"One key has been revoked.");
188 frameColor = SIG_FRAME_COL_RED;
190 if (summary & GpgME::Signature::Red) {
204 showKeyInfos =
false;
206 frameColor = SIG_FRAME_COL_RED;
211 if (SIG_FRAME_COL_GREEN == frameColor) {
212 result =
i18n(
"Good signature.");
213 }
else if (SIG_FRAME_COL_RED == frameColor) {
214 result =
i18n(
"Bad signature.");
237 : mCSSHelper(cssHelper)
238 , mRendererFactory(rendererFactory)
242 DefaultRendererPrivate::~DefaultRendererPrivate() =
default;
251 return mMsgPart->source();
256 for (
const auto &m : msgPart->subParts()) {
257 renderFactory(m, htmlWriter);
270 if (mp->isAttachment()) {
274 renderSubParts(mp, htmlWriter);
281 if (mp->isAttachment()) {
288 renderSubParts(mp, htmlWriter);
293 if (!mp->hasSubParts()) {
296 Grantlee::Template t = MessagePartRendererManager::self()->loadByName(QStringLiteral(
"encapsulatedrfc822messagepart.html"));
297 Grantlee::Context c = MessagePartRendererManager::self()->createContext();
300 c.insert(QStringLiteral(
"block"), &block);
301 block.
setProperty(
"link", mp->nodeHelper()->asHREF(mp->message().
data(), QStringLiteral(
"body")));
303 c.insert(QStringLiteral(
"msgHeader"), mCreateMessageHeader(mp->message().
data()));
304 c.insert(QStringLiteral(
"content"), QVariant::fromValue<GrantleeCallback>([
this, mp, htmlWriter](Grantlee::OutputStream *) {
305 renderSubParts(mp, htmlWriter);
309 if (mp->isAttachment()) {
312 Grantlee::OutputStream s(htmlWriter->
stream());
318 Grantlee::Template t = MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(
"htmlmessagepart.html"));
319 Grantlee::Context c = MessageViewer::MessagePartRendererManager::self()->createContext();
322 c.insert(QStringLiteral(
"block"), &block);
324 auto preferredMode = mp->source()->preferredMode();
327 block.
setProperty(
"loadExternal", htmlLoadExternal());
331 Util::HtmlMessageInfo messageInfo = Util::processHtml(mp->bodyHtml());
333 if (isHtmlPreferred) {
334 mp->nodeHelper()->setNodeDisplayedEmbedded(mp->content(),
true);
335 htmlWriter->setExtraHead(messageInfo.extraHead);
336 htmlWriter->setStyleBody(Util::parseBodyStyle(messageInfo.bodyStyle));
339 block.
setProperty(
"containsExternalReferences", Util::containsExternalReferences(messageInfo.htmlSource, messageInfo.extraHead));
340 c.insert(QStringLiteral(
"content"), messageInfo.htmlSource);
344 ConvertHtmlToPlainText
convert;
345 convert.setHtmlString(mp->bodyHtml());
348 c.
insert(QStringLiteral(
"plaintext"), plaintext);
354 if (mp->isAttachment()) {
357 Grantlee::OutputStream s(htmlWriter->
stream());
364 const auto metaData = *mp->partMetaData();
366 Grantlee::Template t = MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(
"encryptedmessagepart.html"));
367 Grantlee::Context c = MessageViewer::MessagePartRendererManager::self()->createContext();
370 if (node || mp->hasSubParts()) {
371 c.insert(QStringLiteral(
"content"), QVariant::fromValue<GrantleeCallback>([
this, mp, htmlWriter](Grantlee::OutputStream *) {
373 if (mp->content() && mp->isRoot()) {
374 rBlock = HTMLBlock::Ptr(new RootBlock(htmlWriter));
376 renderSubParts(mp, htmlWriter);
378 }
else if (!metaData.inProgress) {
379 c.insert(QStringLiteral(
"content"), QVariant::fromValue<GrantleeCallback>([
this, mp, htmlWriter](Grantlee::OutputStream *) {
380 renderWithFactory<MimeTreeParser::MessagePart>(mp, htmlWriter);
385 if (!mp->decryptRecipients().empty()) {
386 c.insert(QStringLiteral(
"decryptedRecipients"),
QVariant::fromValue(mp->decryptRecipients()));
388 c.insert(QStringLiteral(
"block"), &block);
391 block.
setProperty(
"detailHeader", showEncryptionDetails());
392 block.
setProperty(
"inProgress", metaData.inProgress);
393 block.
setProperty(
"isDecrypted", mp->decryptMessage());
394 block.
setProperty(
"isDecryptable", metaData.isDecryptable);
396 block.
setProperty(
"errorText", metaData.errorText);
399 Grantlee::OutputStream s(htmlWriter->
stream());
406 const auto metaData = *mp->partMetaData();
407 auto cryptoProto = mp->cryptoProto();
409 const bool isSMIME = cryptoProto && (cryptoProto == QGpgME::smime());
411 Grantlee::Template t = MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(
"signedmessagepart.html"));
412 Grantlee::Context c = MessageViewer::MessagePartRendererManager::self()->createContext();
416 c.insert(QStringLiteral(
"content"), QVariant::fromValue<GrantleeCallback>([
this, mp, htmlWriter](Grantlee::OutputStream *) {
419 rBlock = HTMLBlock::Ptr(new RootBlock(htmlWriter));
421 renderSubParts(mp, htmlWriter);
423 }
else if (!metaData.inProgress) {
424 c.insert(QStringLiteral(
"content"), QVariant::fromValue<GrantleeCallback>([
this, mp, htmlWriter](Grantlee::OutputStream *) {
425 renderWithFactory<MimeTreeParser::MessagePart>(mp, htmlWriter);
430 c.insert(QStringLiteral(
"block"), &block);
432 block.
setProperty(
"inProgress", metaData.inProgress);
433 block.
setProperty(
"errorText", metaData.errorText);
435 block.
setProperty(
"detailHeader", showSignatureDetails());
438 block.
setProperty(
"technicalProblem", metaData.technicalProblem);
440 if (metaData.creationTime.isValid()) {
443 block.
setProperty(
"isGoodSignature", metaData.isGoodSignature);
446 if (metaData.keyTrust == GpgME::Signature::Unknown) {
447 block.
setProperty(
"keyTrust", QStringLiteral(
"unknown"));
448 }
else if (metaData.keyTrust == GpgME::Signature::Marginal) {
449 block.
setProperty(
"keyTrust", QStringLiteral(
"marginal"));
450 }
else if (metaData.keyTrust == GpgME::Signature::Full) {
451 block.
setProperty(
"keyTrust", QStringLiteral(
"full"));
452 }
else if (metaData.keyTrust == GpgME::Signature::Ultimate) {
453 block.
setProperty(
"keyTrust", QStringLiteral(
"ultimate"));
455 block.
setProperty(
"keyTrust", QStringLiteral(
"untrusted"));
462 startKeyHREF = QStringLiteral(
"<a href=\"kmail:showCertificate#%1 ### %2 ### %3\">")
469 block.
setProperty(
"keyWithWithoutURL", keyWithWithoutURL);
472 bool onlyShowKeyURL =
false;
473 bool showKeyInfos =
false;
474 bool cannotCheckSignature =
true;
475 QString signer = metaData.signer;
480 if (metaData.inProgress) {
481 mClass = QStringLiteral(
"signInProgress");
483 const QStringList &blockAddrs(metaData.signerMailAddresses);
487 int frameColor = SIG_FRAME_COL_UNDEF;
488 statusStr = sigStatusToString(cryptoProto, metaData.status_code, metaData.sigSummary, frameColor, showKeyInfos);
492 statusStr = metaData.status;
494 if (metaData.technicalProblem) {
495 frameColor = SIG_FRAME_COL_YELLOW;
498 switch (frameColor) {
499 case SIG_FRAME_COL_RED:
500 cannotCheckSignature =
false;
502 case SIG_FRAME_COL_YELLOW:
503 cannotCheckSignature =
true;
505 case SIG_FRAME_COL_GREEN:
506 cannotCheckSignature =
false;
513 if (isSMIME && (SIG_FRAME_COL_UNDEF != frameColor)) {
514 switch (frameColor) {
515 case SIG_FRAME_COL_RED:
516 mClass = QStringLiteral(
"signErr");
517 onlyShowKeyURL =
true;
519 case SIG_FRAME_COL_YELLOW:
520 if (metaData.technicalProblem) {
521 mClass = QStringLiteral(
"signWarn");
523 mClass = QStringLiteral(
"signOkKeyBad");
526 case SIG_FRAME_COL_GREEN:
527 mClass = QStringLiteral(
"signOkKeyOk");
532 if (metaData.keyId.isEmpty()) {
533 certificate =
i18n(
"certificate");
535 certificate = startKeyHREF +
i18n(
"certificate") + QStringLiteral(
"</a>");
538 if (!blockAddrs.empty()) {
540 greenCaseWarning = QStringLiteral(
"<u>") +
i18nc(
"Start of warning message.",
"Warning:") + QStringLiteral(
"</u> ")
541 +
i18n(
"Sender's mail address is not stored in the %1 used for signing.", certificate) + QStringLiteral(
"<br />") +
i18n(
"sender: ")
542 + msgFrom + QStringLiteral(
"<br />") +
i18n(
"stored: ");
559 greenCaseWarning = QStringLiteral(
"<u>") +
i18nc(
"Start of warning message.",
"Warning:") + QStringLiteral(
"</u> ")
560 +
i18n(
"No mail address is stored in the %1 used for signing, "
561 "so we cannot compare it to the sender's address %2.",
568 if (showKeyInfos && !cannotCheckSignature) {
569 if (metaData.signer.isEmpty()) {
572 if (!blockAddrs.empty()) {
579 if (metaData.signer.isEmpty() || metaData.technicalProblem) {
580 mClass = QStringLiteral(
"signWarn");
584 signer = QStringLiteral(
"<a href=\"mailto:%1\">%1</a>").
arg(signer);
586 if (metaData.isGoodSignature) {
587 if (metaData.keyTrust < GpgME::Signature::Marginal) {
588 mClass = QStringLiteral(
"signOkKeyBad");
590 mClass = QStringLiteral(
"signOkKeyOk");
593 mClass = QStringLiteral(
"signErr");
599 block.
setProperty(
"onlyShowKeyURL", onlyShowKeyURL);
601 block.
setProperty(
"cannotCheckSignature", cannotCheckSignature);
605 block.
setProperty(
"greenCaseWarning", greenCaseWarning);
607 Grantlee::OutputStream s(htmlWriter->
stream());
613 const auto metaData = *mp->partMetaData();
614 if (metaData.isSigned || metaData.inProgress) {
616 if (mp->isAttachment()) {
619 renderSigned(mp, htmlWriter);
624 if (mp->isAttachment()) {
627 if (mp->hasSubParts()) {
628 renderSubParts(mp, htmlWriter);
629 }
else if (!metaData.inProgress) {
630 renderWithFactory<MimeTreeParser::MessagePart>(mp, htmlWriter);
636 const auto metaData = *mp->partMetaData();
638 if (metaData.isEncrypted || metaData.inProgress) {
640 if (mp->isAttachment()) {
643 renderEncrypted(mp, htmlWriter);
648 if (mp->isAttachment()) {
652 if (mp->hasSubParts()) {
653 renderSubParts(mp, htmlWriter);
654 }
else if (!metaData.inProgress) {
655 renderWithFactory<MimeTreeParser::MessagePart>(mp, htmlWriter);
662 if (mp->isAttachment()) {
666 auto mode = mp->preferredMode();
668 const auto availableModes = mp->availableModes();
669 for (
const auto m : availableModes) {
677 if (mp->childParts().contains(mode)) {
678 part = mp->childParts()[mode];
681 render(part, htmlWriter);
686 const GpgME::ImportResult &importResult(mp->importResult());
687 Grantlee::Template t = MessageViewer::MessagePartRendererManager::self()->loadByName(QStringLiteral(
"certmessagepart.html"));
688 Grantlee::Context c = MessageViewer::MessagePartRendererManager::self()->createContext();
691 c.insert(QStringLiteral(
"block"), &block);
693 block.
setProperty(
"nImp", importResult.numImported());
694 block.
setProperty(
"nUnc", importResult.numUnchanged());
695 block.
setProperty(
"nSKImp", importResult.numSecretKeysImported());
696 block.
setProperty(
"nSKUnc", importResult.numSecretKeysUnchanged());
698 QVariantList keylist;
699 const auto imports = importResult.imports();
701 auto end(imports.end());
702 for (
auto it = imports.begin(); it != end; ++it) {
705 key->setProperty(
"status", (*it).status());
706 key->setProperty(
"fingerprint",
QLatin1String((*it).fingerprint()));
711 if (mp->isAttachment()) {
714 Grantlee::OutputStream s(htmlWriter->
stream());
720 if (!mRendererFactory) {
723 for (
auto r : mRendererFactory->renderersForPart(mo, msgPart)) {
724 if (r->render(msgPart, htmlWriter,
this)) {
735 if (isHiddenHint(msgPart)) {
736 const QByteArray cid = msgPart->content()->contentID()->identifier();
739 QString fileName = mp->temporaryFilePath();
745 if (renderWithFactory(msgPart, htmlWriter)) {
749 if (className ==
QLatin1String(
"MimeTreeParser::MessagePartList")) {
752 render(mp, htmlWriter);
754 }
else if (className ==
QLatin1String(
"MimeTreeParser::MimeMessagePart")) {
757 render(mp, htmlWriter);
759 }
else if (className ==
QLatin1String(
"MimeTreeParser::EncapsulatedRfc822MessagePart")) {
762 render(mp, htmlWriter);
764 }
else if (className ==
QLatin1String(
"MimeTreeParser::HtmlMessagePart")) {
767 render(mp, htmlWriter);
769 }
else if (className ==
QLatin1String(
"MimeTreeParser::SignedMessagePart")) {
772 render(mp, htmlWriter);
774 }
else if (className ==
QLatin1String(
"MimeTreeParser::EncryptedMessagePart")) {
777 render(mp, htmlWriter);
779 }
else if (className ==
QLatin1String(
"MimeTreeParser::AlternativeMessagePart")) {
782 render(mp, htmlWriter);
784 }
else if (className ==
QLatin1String(
"MimeTreeParser::CertMessagePart")) {
787 render(mp, htmlWriter);
790 qCWarning(MESSAGEVIEWER_LOG) <<
"We got a unknown classname, using default behaviour for " << className;
797 auto content = msgPart->content();
799 if (!mp || !content) {
803 if (mShowOnlyOneMimePart && mMsgPart.data() == msgPart->parentPart()) {
804 if (mMsgPart->subParts().at(0) == msgPart.
data()) {
809 if (msgPart->nodeHelper()->isNodeDisplayedHidden(content)) {
814 const bool defaultHidden(as && as->defaultDisplay(content) == AttachmentStrategy::None);
815 auto preferredMode = source()->preferredMode();
819 if (content->contentType(
false) && !content->contentType(
false)->mediaType().isEmpty() && !content->contentType(
false)->subType().isEmpty()) {
820 mediaType = content->contentType(
false)->mediaType();
822 const bool isTextPart = (mediaType == QByteArrayLiteral(
"text"));
824 bool defaultAsIcon =
true;
825 if (!mp->neverDisplayInline()) {
827 defaultAsIcon = as->defaultDisplay(content) == AttachmentStrategy::AsIcon;
832 if (!mp->isImage() && !isTextPart) {
833 defaultAsIcon =
true;
838 hidden = defaultHidden;
840 if (mp->isImage() && isHtmlPreferred && content->
parent() && content->
parent()->contentType(
false)->subType() ==
"related") {
843 hidden = defaultHidden && content->
parent();
844 hidden |= defaultAsIcon && defaultHidden;
847 msgPart->nodeHelper()->setNodeDisplayedHidden(content, hidden);
854 auto content = msgPart->content();
856 if (!content || !mp) {
857 return MimeTreeParser::IconType::NoIcon;
861 const bool defaultDisplayHidden(as && as->defaultDisplay(content) == AttachmentStrategy::None);
862 const bool defaultDisplayInline(as && as->defaultDisplay(content) == AttachmentStrategy::Inline);
863 const bool defaultDisplayAsIcon(as && as->defaultDisplay(content) == AttachmentStrategy::AsIcon);
864 const bool showOnlyOneMimePart(mShowOnlyOneMimePart);
865 auto preferredMode = source()->preferredMode();
869 if (content->contentType(
false) && !content->contentType(
false)->mediaType().isEmpty() && !content->contentType(
false)->subType().isEmpty()) {
870 mediaType = content->contentType(
false)->mediaType();
872 const bool isTextPart = (mediaType == QByteArrayLiteral(
"text"));
874 bool defaultAsIcon =
true;
875 if (!mp->neverDisplayInline()) {
877 defaultAsIcon = defaultDisplayAsIcon;
880 if (mp->isImage() && showOnlyOneMimePart && !mp->neverDisplayInline()) {
881 defaultAsIcon =
false;
885 if (!mp->isImage() && !isTextPart) {
886 defaultAsIcon =
true;
890 if (as && !defaultDisplayInline) {
891 return MimeTreeParser::IconExternal;
893 return MimeTreeParser::NoIcon;
895 if (mp->isImage() && isHtmlPreferred && content->
parent() && content->
parent()->contentType(
false)->subType() ==
"related") {
896 return MimeTreeParser::IconInline;
899 if (defaultDisplayHidden && !showOnlyOneMimePart && content->
parent()) {
900 return MimeTreeParser::IconInline;
904 return MimeTreeParser::IconExternal;
905 }
else if (mp->isImage()) {
906 return MimeTreeParser::IconInline;
910 return MimeTreeParser::NoIcon;
913 bool DefaultRendererPrivate::showEmoticons()
const
915 return mShowEmoticons;
918 bool DefaultRendererPrivate::isPrinting()
const
923 bool DefaultRendererPrivate::htmlLoadExternal()
const
925 return mHtmlLoadExternal;
928 bool DefaultRendererPrivate::showExpandQuotesMark()
const
930 return mShowExpandQuotesMark;
933 bool DefaultRendererPrivate::showOnlyOneMimePart()
const
935 return mShowOnlyOneMimePart;
938 bool DefaultRendererPrivate::showSignatureDetails()
const
940 return mShowSignatureDetails;
943 bool DefaultRendererPrivate::showEncryptionDetails()
const
945 return mShowEncryptionDetails;
948 int DefaultRendererPrivate::levelQuote()
const
958 DefaultRenderer::~DefaultRenderer() =
default;
960 void DefaultRenderer::setShowOnlyOneMimePart(
bool onlyOneMimePart)
962 d->mShowOnlyOneMimePart = onlyOneMimePart;
967 d->mAttachmentStrategy = strategy;
970 void DefaultRenderer::setShowEmoticons(
bool showEmoticons)
972 d->mShowEmoticons = showEmoticons;
975 void DefaultRenderer::setIsPrinting(
bool isPrinting)
977 d->mIsPrinting = isPrinting;
980 void DefaultRenderer::setShowExpandQuotesMark(
bool showExpandQuotesMark)
982 d->mShowExpandQuotesMark = showExpandQuotesMark;
985 void DefaultRenderer::setShowEncryptionDetails(
bool showEncryptionDetails)
987 d->mShowEncryptionDetails = showEncryptionDetails;
990 void DefaultRenderer::setShowSignatureDetails(
bool showSignatureDetails)
992 d->mShowSignatureDetails = showSignatureDetails;
995 void DefaultRenderer::setLevelQuote(
int levelQuote)
997 d->mLevelQuote = levelQuote;
1000 void DefaultRenderer::setHtmlLoadExternal(
bool htmlLoadExternal)
1002 d->mHtmlLoadExternal = htmlLoadExternal;
1005 void DefaultRenderer::setCreateMessageHeader(
const std::function<
QString(
KMime::Message *)> &createMessageHeader)
1007 d->mCreateMessageHeader = createMessageHeader;
1014 for (
const auto &subPart : messagePart->subParts()) {
1015 ret += renderTreeHelper(subPart, indent);
1022 qCDebug(MESSAGEVIEWER_LOG) <<
"MimeTreeParser structure:";
1023 qCDebug(MESSAGEVIEWER_LOG) << qPrintable(renderTreeHelper(msgPart,
QString()));
1024 d->mMsgPart = msgPart;
1025 d->renderFactory(d->mMsgPart, writer);