summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandro KnauƟ <sknauss@kde.org>2016-07-26 10:17:10 (GMT)
committerMontel Laurent <montel@kde.org>2016-07-26 11:15:55 (GMT)
commitd8d0f65a88ccf524b8d2fb88fe9d5ad07409fd52 (patch)
tree6a6e614a7c4110631f8503df8dd3c8c4bfe71540
parentdf0a5908b9b876cfda859818dd3c64ca42c3845d (diff)
Render multipart/alternative with a invitation correctly
alternative parts can also have a calender element, so we want to render that. BUG: 362958
-rw-r--r--messageviewer/src/messagepartthemes/default/autotests/objecttreeparsertest.cpp12
-rw-r--r--messageviewer/src/messagepartthemes/default/autotests/setupenv.h25
-rw-r--r--messageviewer/src/messagepartthemes/default/defaultrenderer.cpp25
-rw-r--r--messageviewer/src/viewer/objecttreeemptysource.cpp13
-rw-r--r--messageviewer/src/viewer/objecttreeemptysource.h4
-rw-r--r--messageviewer/src/viewer/objecttreeviewersource.cpp25
-rw-r--r--messageviewer/src/viewer/objecttreeviewersource.h4
-rw-r--r--messageviewer/src/viewer/viewer.h3
-rw-r--r--messageviewer/src/viewer/viewer_p.cpp29
-rw-r--r--messageviewer/src/viewer/viewer_p.h2
-rw-r--r--messageviewer/src/widgets/htmlstatusbar.cpp19
-rw-r--r--messageviewer/src/widgets/htmlstatusbar.h4
-rw-r--r--mimetreeparser/autotests/setupenv.h25
-rw-r--r--mimetreeparser/src/bodyformatter/multipartalternative.cpp61
-rw-r--r--mimetreeparser/src/interfaces/objecttreesource.h7
-rw-r--r--mimetreeparser/src/utils/util.h3
-rw-r--r--mimetreeparser/src/viewer/messagepart.cpp100
-rw-r--r--mimetreeparser/src/viewer/messagepart.h22
-rw-r--r--mimetreeparser/src/viewer/objecttreeparser.cpp8
19 files changed, 247 insertions, 144 deletions
diff --git a/messageviewer/src/messagepartthemes/default/autotests/objecttreeparsertest.cpp b/messageviewer/src/messagepartthemes/default/autotests/objecttreeparsertest.cpp
index 335d5d0..d5d006c 100644
--- a/messageviewer/src/messagepartthemes/default/autotests/objecttreeparsertest.cpp
+++ b/messageviewer/src/messagepartthemes/default/autotests/objecttreeparsertest.cpp
@@ -210,7 +210,7 @@ void ObjectTreeParserTester::test_HTMLasText()
Test::CSSHelper testCSSHelper;
Test::ObjectTreeSource emptySource(&testWriter, &testCSSHelper);
ObjectTreeParser otp(&emptySource);
- emptySource.setHtmlMail(false);
+ emptySource.setPreferredMode(MimeTreeParser::Util::MultipartPlain);
otp.parseObjectTree(msg.data());
QCOMPARE(otp.htmlContent().toLatin1().constData(), "");
@@ -247,7 +247,7 @@ void ObjectTreeParserTester::test_HTMLOnlyText()
Test::ObjectTreeSource emptySource(&testWriter, &testCSSHelper);
ObjectTreeParser otp(&emptySource);
- emptySource.setHtmlMail(false);
+ emptySource.setPreferredMode(MimeTreeParser::Util::MultipartPlain);
otp.parseObjectTree(msg.data());
QVERIFY(otp.plainTextContent().isEmpty());
@@ -301,7 +301,7 @@ void ObjectTreeParserTester::test_Alternative()
Test::ObjectTreeSource emptySource(&testWriter, &testCSSHelper);
ObjectTreeParser otp(&emptySource);
- emptySource.setHtmlMail(false);
+ emptySource.setPreferredMode(MimeTreeParser::Util::MultipartPlain);
otp.parseObjectTree(msg.data());
QVERIFY(otp.htmlContent().isEmpty());
@@ -315,7 +315,7 @@ void ObjectTreeParserTester::test_Alternative()
Test::ObjectTreeSource emptySource(&testWriter, &testCSSHelper);
ObjectTreeParser otp(&emptySource);
- emptySource.setHtmlMail(true);
+ emptySource.setPreferredMode(MimeTreeParser::Util::MultipartHtml);
otp.parseObjectTree(msg.data());
QVERIFY(otp.plainTextContent().contains(QStringLiteral("If you can see this text it means that your email client couldn't display our newsletter properly.")));
@@ -331,7 +331,7 @@ void ObjectTreeParserTester::test_Alternative()
Test::ObjectTreeSource emptySource(&testWriter, &testCSSHelper);
ObjectTreeParser otp(&emptySource);
- emptySource.setHtmlMail(false);
+ emptySource.setPreferredMode(MimeTreeParser::Util::MultipartPlain);
otp.parseObjectTree(msg.data());
QVERIFY(otp.plainTextContent().isEmpty());
@@ -345,7 +345,7 @@ void ObjectTreeParserTester::test_Alternative()
Test::ObjectTreeSource emptySource(&testWriter, &testCSSHelper);
ObjectTreeParser otp(&emptySource);
- emptySource.setHtmlMail(true);
+ emptySource.setPreferredMode(MimeTreeParser::Util::MultipartHtml);
otp.parseObjectTree(msg.data());
QVERIFY(otp.plainTextContent().isEmpty());
diff --git a/messageviewer/src/messagepartthemes/default/autotests/setupenv.h b/messageviewer/src/messagepartthemes/default/autotests/setupenv.h
index 8f0cbb9..bb928dc 100644
--- a/messageviewer/src/messagepartthemes/default/autotests/setupenv.h
+++ b/messageviewer/src/messagepartthemes/default/autotests/setupenv.h
@@ -53,8 +53,8 @@ public:
, mCSSHelper(cssHelper)
, mAttachmentStrategy(QStringLiteral("smart"))
, mHtmlLoadExternal(false)
- , mHtmlMail(true)
, mDecryptMessage(false)
+ , mPreferredMode(MimeTreeParser::Util::Html)
{
}
@@ -76,16 +76,6 @@ public:
mHtmlLoadExternal = loadExternal;
}
- bool htmlMail() const Q_DECL_OVERRIDE
- {
- return mHtmlMail;
- }
-
- void setHtmlMail(bool htmlMail)
- {
- mHtmlMail = htmlMail;
- }
-
void setAttachmentStrategy(QString strategy)
{
mAttachmentStrategy = strategy;
@@ -134,8 +124,17 @@ public:
return mShowSignatureDetails;
}
- void setHtmlMode(MimeTreeParser::Util::HtmlMode mode) Q_DECL_OVERRIDE {
+ void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes) Q_DECL_OVERRIDE {
Q_UNUSED(mode);
+ Q_UNUSED(availableModes);
+ }
+
+ MimeTreeParser::Util::HtmlMode preferredMode() const Q_DECL_OVERRIDE {
+ return mPreferredMode;
+ }
+
+ void setPreferredMode(MimeTreeParser::Util::HtmlMode mode) {
+ mPreferredMode = mode;
}
int levelQuote() const Q_DECL_OVERRIDE
@@ -162,9 +161,9 @@ private:
QString mAttachmentStrategy;
MimeTreeParser::BodyPartFormatterBaseFactory mBodyPartFormatterBaseFactory;
bool mHtmlLoadExternal;
- bool mHtmlMail;
bool mDecryptMessage;
bool mShowSignatureDetails;
+ MimeTreeParser::Util::HtmlMode mPreferredMode;
};
}
diff --git a/messageviewer/src/messagepartthemes/default/defaultrenderer.cpp b/messageviewer/src/messagepartthemes/default/defaultrenderer.cpp
index 64786dd..6156f28 100644
--- a/messageviewer/src/messagepartthemes/default/defaultrenderer.cpp
+++ b/messageviewer/src/messagepartthemes/default/defaultrenderer.cpp
@@ -873,14 +873,16 @@ public:
c.insert(QStringLiteral("block"), &block);
- block.setProperty("htmlMail", mp->source()->htmlMail());
+ auto preferredMode = mp->source()->preferredMode();
+ bool isHtmlPreferred = (preferredMode == Util::Html) || (preferredMode == Util::MultipartHtml);
+ block.setProperty("htmlMail", isHtmlPreferred);
block.setProperty("loadExternal", mp->source()->htmlLoadExternal());
{
QString extraHead;
QString bodyText = processHtml(mp->mBodyHTML, extraHead);
- if (mp->source()->htmlMail()) {
+ if (isHtmlPreferred) {
mp->mOtp->nodeHelper()->setNodeDisplayedEmbedded(mp->mNode, true);
mOldWriter->extraHead(extraHead);
}
@@ -896,7 +898,7 @@ public:
plaintext.replace(QLatin1String("\n"), QStringLiteral("<br>"));
c.insert(QStringLiteral("plaintext"), plaintext);
}
- mp->source()->setHtmlMode(Util::Html);
+ mp->source()->setHtmlMode(Util::Html, QList<Util::HtmlMode>() << Util::Html);
auto htmlWriter = QSharedPointer<CacheHtmlWriter>(new CacheHtmlWriter(mOldWriter));
{
@@ -1252,11 +1254,18 @@ public:
aBlock = HTMLBlock::Ptr(new AttachmentMarkBlock(htmlWriter.data(), mp->attachmentNode()));
}
- MimeMessagePart::Ptr part(mp->mTextPart);
- if (mp->viewHtml() && mp->mHTMLPart) {
- part = mp->mHTMLPart;
- } else if (mp->text().trimmed().isEmpty()) {
- part = mp->mHTMLPart;
+ auto mode = mp->preferredMode();
+ if (mode == MimeTreeParser::Util::MultipartPlain && mp->text().trimmed().isEmpty()) {
+ foreach(const auto m, mp->availableModes()) {
+ if (m != MimeTreeParser::Util::MultipartPlain) {
+ mode = m;
+ break;
+ }
+ }
+ }
+ MimeMessagePart::Ptr part(mp->mChildParts.first());
+ if (mp->mChildParts.contains(mode)) {
+ part = mp->mChildParts[mode];
}
htmlWriter->queue(render(part));
diff --git a/messageviewer/src/viewer/objecttreeemptysource.cpp b/messageviewer/src/viewer/objecttreeemptysource.cpp
index d69fe83..0b1e185 100644
--- a/messageviewer/src/viewer/objecttreeemptysource.cpp
+++ b/messageviewer/src/viewer/objecttreeemptysource.cpp
@@ -57,11 +57,6 @@ EmptySource::~EmptySource()
delete d;
}
-bool EmptySource::htmlMail() const
-{
- return true;
-}
-
bool EmptySource::decryptMessage() const
{
return d->mAllowDecryption;
@@ -77,9 +72,15 @@ bool EmptySource::showSignatureDetails() const
return false;
}
-void EmptySource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode)
+void EmptySource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes)
{
Q_UNUSED(mode);
+ Q_UNUSED(availableModes);
+}
+
+MimeTreeParser::Util::HtmlMode EmptySource::preferredMode() const
+{
+ return MimeTreeParser::Util::Html;
}
void EmptySource::setAllowDecryption(bool allowDecryption)
diff --git a/messageviewer/src/viewer/objecttreeemptysource.h b/messageviewer/src/viewer/objecttreeemptysource.h
index 4cd4d5d..45bfced 100644
--- a/messageviewer/src/viewer/objecttreeemptysource.h
+++ b/messageviewer/src/viewer/objecttreeemptysource.h
@@ -35,11 +35,11 @@ class MESSAGEVIEWER_EXPORT EmptySource : public MimeTreeParser::Interface::Objec
public:
EmptySource();
~EmptySource();
- bool htmlMail() const Q_DECL_OVERRIDE;
bool decryptMessage() const Q_DECL_OVERRIDE;
bool htmlLoadExternal() const Q_DECL_OVERRIDE;
bool showSignatureDetails() const Q_DECL_OVERRIDE;
- void setHtmlMode(MimeTreeParser::Util::HtmlMode mode) Q_DECL_OVERRIDE;
+ void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes) Q_DECL_OVERRIDE;
+ MimeTreeParser::Util::HtmlMode preferredMode() const Q_DECL_OVERRIDE;
void setAllowDecryption(bool allowDecryption);
int levelQuote() const Q_DECL_OVERRIDE;
const QTextCodec *overrideCodec() Q_DECL_OVERRIDE;
diff --git a/messageviewer/src/viewer/objecttreeviewersource.cpp b/messageviewer/src/viewer/objecttreeviewersource.cpp
index 8861d85..9b955b8 100644
--- a/messageviewer/src/viewer/objecttreeviewersource.cpp
+++ b/messageviewer/src/viewer/objecttreeviewersource.cpp
@@ -39,11 +39,6 @@ MailViewerSource::~MailViewerSource()
{
}
-bool MailViewerSource::htmlMail() const
-{
- return mViewer->htmlMail();
-}
-
bool MailViewerSource::decryptMessage() const
{
return mViewer->decryptMessage();
@@ -59,11 +54,29 @@ bool MailViewerSource::showSignatureDetails() const
return mViewer->mShowSignatureDetails;
}
-void MailViewerSource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode)
+void MailViewerSource::setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes)
{
+ mViewer->mColorBar->setAvailableModes(availableModes);
mViewer->mColorBar->setMode(mode);
}
+MimeTreeParser::Util::HtmlMode MailViewerSource::preferredMode() const
+{
+ switch (mViewer->displayFormatMessageOverwrite()) {
+ case MessageViewer::Viewer::UseGlobalSetting:
+ case MessageViewer::Viewer::Unknown:
+ return mViewer->htmlMailGlobalSetting() ? MimeTreeParser::Util::Html : MimeTreeParser::Util::Normal;
+ case MessageViewer::Viewer::Html:
+ return MimeTreeParser::Util::MultipartHtml;
+ case MessageViewer::Viewer::Text:
+ return MimeTreeParser::Util::MultipartPlain;
+ case MessageViewer::Viewer::ICal:
+ return MimeTreeParser::Util::MultipartIcal;
+ }
+ Q_ASSERT(true);
+ return MimeTreeParser::Util::Html;
+}
+
int MailViewerSource::levelQuote() const
{
return mViewer->mLevelQuote;
diff --git a/messageviewer/src/viewer/objecttreeviewersource.h b/messageviewer/src/viewer/objecttreeviewersource.h
index 6b0b340..1ef25bb 100644
--- a/messageviewer/src/viewer/objecttreeviewersource.h
+++ b/messageviewer/src/viewer/objecttreeviewersource.h
@@ -35,11 +35,11 @@ class MailViewerSource : public MimeTreeParser::Interface::ObjectTreeSource
public:
explicit MailViewerSource(ViewerPrivate *viewer);
~MailViewerSource();
- bool htmlMail() const Q_DECL_OVERRIDE;
bool decryptMessage() const Q_DECL_OVERRIDE;
bool htmlLoadExternal() const Q_DECL_OVERRIDE;
bool showSignatureDetails() const Q_DECL_OVERRIDE;
- void setHtmlMode(MimeTreeParser::Util::HtmlMode mode) Q_DECL_OVERRIDE;
+ void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes) Q_DECL_OVERRIDE;
+ MimeTreeParser::Util::HtmlMode preferredMode() const Q_DECL_OVERRIDE;
int levelQuote() const Q_DECL_OVERRIDE;
const QTextCodec *overrideCodec() Q_DECL_OVERRIDE;
QString createMessageHeader(KMime::Message *message) Q_DECL_OVERRIDE;
diff --git a/messageviewer/src/viewer/viewer.h b/messageviewer/src/viewer/viewer.h
index 49a4c03..0a7a048 100644
--- a/messageviewer/src/viewer/viewer.h
+++ b/messageviewer/src/viewer/viewer.h
@@ -122,7 +122,8 @@ public:
UseGlobalSetting = 0,
Text = 1,
Html = 2,
- Unknown = 3
+ Unknown = 3,
+ ICal = 4
};
enum AttachmentAction {
diff --git a/messageviewer/src/viewer/viewer_p.cpp b/messageviewer/src/viewer/viewer_p.cpp
index 4eabd1b..2ef8b44 100644
--- a/messageviewer/src/viewer/viewer_p.cpp
+++ b/messageviewer/src/viewer/viewer_p.cpp
@@ -1260,6 +1260,7 @@ void ViewerPrivate::resetStateForNewMessage()
mViewerPluginToolManager->closeAllTools();
mScamDetectionWarning->setVisible(false);
mOpenAttachmentFolderWidget->setVisible(false);
+ mDisplayFormatMessageOverwrite = (mDisplayFormatMessageOverwrite == MessageViewer::Viewer::UseGlobalSetting) ? MessageViewer::Viewer::UseGlobalSetting : MessageViewer::Viewer::Unknown;
if (mPrinting) {
if (MessageViewer::MessageViewerSettings::self()->respectExpandCollapseSettings()) {
@@ -2012,14 +2013,33 @@ void ViewerPrivate::slotLoadExternalReference()
update(MimeTreeParser::Force);
}
+Viewer::DisplayFormatMessage translateToDisplayFormat(MimeTreeParser::Util::HtmlMode mode)
+{
+ switch(mode) {
+ case MimeTreeParser::Util::Normal:
+ return Viewer::Unknown;
+ case MimeTreeParser::Util::Html:
+ return Viewer::Html;
+ case MimeTreeParser::Util::MultipartPlain:
+ return Viewer::Text;
+ case MimeTreeParser::Util::MultipartHtml:
+ return Viewer::Html;
+ case MimeTreeParser::Util::MultipartIcal:
+ return Viewer::ICal;
+ }
+ return Viewer::Unknown;
+}
+
void ViewerPrivate::slotToggleHtmlMode()
{
if (mColorBar->isNormal()) {
return;
}
mScamDetectionWarning->setVisible(false);
- const bool useHtml = !htmlMail();
- setDisplayFormatMessageOverwrite(useHtml ? MessageViewer::Viewer::Html : MessageViewer::Viewer::Text);
+ const auto availableModes = mColorBar->availableModes();
+ const MimeTreeParser::Util::HtmlMode mode = mColorBar->mode();
+ const int pos = (availableModes.indexOf(mode) + 1) % availableModes.size();
+ setDisplayFormatMessageOverwrite(translateToDisplayFormat(availableModes[pos]));
update(MimeTreeParser::Force);
}
@@ -2686,6 +2706,11 @@ void ViewerPrivate::setDisplayFormatMessageOverwrite(Viewer::DisplayFormatMessag
}
}
+bool ViewerPrivate::htmlMailGlobalSetting() const
+{
+ return mHtmlMailGlobalSetting;
+}
+
Viewer::DisplayFormatMessage ViewerPrivate::displayFormatMessageOverwrite() const
{
return mDisplayFormatMessageOverwrite;
diff --git a/messageviewer/src/viewer/viewer_p.h b/messageviewer/src/viewer/viewer_p.h
index edba31e..52e7fc7 100644
--- a/messageviewer/src/viewer/viewer_p.h
+++ b/messageviewer/src/viewer/viewer_p.h
@@ -371,6 +371,8 @@ public:
bool htmlMail() const;
bool htmlLoadExternal() const;
+ bool htmlMailGlobalSetting() const;
+
/** Get the html override setting */
Viewer::DisplayFormatMessage displayFormatMessageOverwrite() const;
diff --git a/messageviewer/src/widgets/htmlstatusbar.cpp b/messageviewer/src/widgets/htmlstatusbar.cpp
index 39a85cd..fa64d30 100644
--- a/messageviewer/src/widgets/htmlstatusbar.cpp
+++ b/messageviewer/src/widgets/htmlstatusbar.cpp
@@ -109,6 +109,16 @@ void HtmlStatusBar::setMultipartHtmlMode()
setMode(MimeTreeParser::Util::MultipartHtml);
}
+void HtmlStatusBar::setAvailableModes(const QList<MimeTreeParser::Util::HtmlMode> &availableModes)
+{
+ mAvailableModes = availableModes;
+}
+
+const QList< MimeTreeParser::Util::HtmlMode >& HtmlStatusBar::availableModes()
+{
+ return mAvailableModes;
+}
+
void HtmlStatusBar::setMode(MimeTreeParser::Util::HtmlMode m, UpdateMode mode)
{
if (mMode != m) {
@@ -143,6 +153,10 @@ QString HtmlStatusBar::message() const
return i18nc("'Plain Message' with html linebreaks between each letter.",
"<qt><br />P<br />l<br />a<br />i<br />n<br /> "
"<br />M<br />e<br />s<br />s<br />a<br />g<br />e<br /></qt>");
+ case MimeTreeParser::Util::MultipartIcal: // normal: "Calendar Message"
+ return i18nc("'Calendar Message' with html linebreaks between each letter.",
+ "<qt><br />C<br />a<br />l<br />l<br />e<br />n<br />d<br />a<br />r<br /> "
+ "<br />M<br />e<br />s<br />s<br />a<br />g<br />e<br /></qt>");
default:
return QString();
}
@@ -154,7 +168,8 @@ QString HtmlStatusBar::toolTip() const
case MimeTreeParser::Util::Html:
case MimeTreeParser::Util::MultipartHtml:
case MimeTreeParser::Util::MultipartPlain:
- return i18n("Click to toggle between HTML and plain text.");
+ case MimeTreeParser::Util::MultipartIcal:
+ return i18n("Click to toggle between HTML, plain text and calendar.");
default:
case MimeTreeParser::Util::Normal:
break;
@@ -178,6 +193,7 @@ QColor HtmlStatusBar::fgColor() const
return color;
case MimeTreeParser::Util::Normal:
case MimeTreeParser::Util::MultipartPlain:
+ case MimeTreeParser::Util::MultipartIcal:
defaultColor = Qt::black;
color = defaultColor;
if (!MessageCore::MessageCoreSettings::self()->useDefaultColors()) {
@@ -205,6 +221,7 @@ QColor HtmlStatusBar::bgColor() const
return color;
case MimeTreeParser::Util::Normal:
case MimeTreeParser::Util::MultipartPlain:
+ case MimeTreeParser::Util::MultipartIcal:
defaultColor = Qt::lightGray;
color = defaultColor;
if (!MessageCore::MessageCoreSettings::self()->useDefaultColors()) {
diff --git a/messageviewer/src/widgets/htmlstatusbar.h b/messageviewer/src/widgets/htmlstatusbar.h
index 029f282..bae3569 100644
--- a/messageviewer/src/widgets/htmlstatusbar.h
+++ b/messageviewer/src/widgets/htmlstatusbar.h
@@ -84,6 +84,9 @@ public:
// Update the status bar, for example when the color scheme changed.
void update();
+ void setAvailableModes(const QList<MimeTreeParser::Util::HtmlMode> &availableModes);
+ const QList<MimeTreeParser::Util::HtmlMode> &availableModes();
+
public Q_SLOTS:
void setHtmlMode();
/** Switch to "normal mode". */
@@ -109,6 +112,7 @@ private:
QColor fgColor() const;
MimeTreeParser::Util::HtmlMode mMode;
+ QList<MimeTreeParser::Util::HtmlMode> mAvailableModes;
};
}
diff --git a/mimetreeparser/autotests/setupenv.h b/mimetreeparser/autotests/setupenv.h
index f8a1c21..3550429 100644
--- a/mimetreeparser/autotests/setupenv.h
+++ b/mimetreeparser/autotests/setupenv.h
@@ -49,8 +49,8 @@ public:
TestObjectTreeSource(MimeTreeParser::HtmlWriter *writer)
: mWriter(writer)
, mAttachmentStrategy(QStringLiteral("smart"))
+ , mPreferredMode(Util::Html)
, mHtmlLoadExternal(false)
- , mHtmlMail(true)
, mDecryptMessage(false)
{
}
@@ -69,16 +69,6 @@ public:
mHtmlLoadExternal = loadExternal;
}
- bool htmlMail() const Q_DECL_OVERRIDE
- {
- return mHtmlMail;
- }
-
- void setHtmlMail(bool htmlMail)
- {
- mHtmlMail = htmlMail;
- }
-
void setAttachmentStrategy(QString strategy)
{
mAttachmentStrategy = strategy;
@@ -127,8 +117,17 @@ public:
return mShowSignatureDetails;
}
- void setHtmlMode(MimeTreeParser::Util::HtmlMode mode) Q_DECL_OVERRIDE {
+ void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes) Q_DECL_OVERRIDE {
Q_UNUSED(mode);
+ Q_UNUSED(availableModes);
+ }
+
+ MimeTreeParser::Util::HtmlMode preferredMode() const Q_DECL_OVERRIDE {
+ return mPreferredMode;
+ }
+
+ void setPreferredMode( MimeTreeParser::Util::HtmlMode mode) {
+ mPreferredMode = mode;
}
int levelQuote() const Q_DECL_OVERRIDE
@@ -157,8 +156,8 @@ private:
MimeTreeParser::HtmlWriter *mWriter;
QString mAttachmentStrategy;
BodyPartFormatterBaseFactory mBodyPartFormatterBaseFactory;
+ MimeTreeParser::Util::HtmlMode mPreferredMode;
bool mHtmlLoadExternal;
- bool mHtmlMail;
bool mDecryptMessage;
bool mShowSignatureDetails;
};
diff --git a/mimetreeparser/src/bodyformatter/multipartalternative.cpp b/mimetreeparser/src/bodyformatter/multipartalternative.cpp
index 23abc13..ed3f218 100644
--- a/mimetreeparser/src/bodyformatter/multipartalternative.cpp
+++ b/mimetreeparser/src/bodyformatter/multipartalternative.cpp
@@ -58,46 +58,37 @@ Interface::MessagePart::Ptr MultiPartAlternativeBodyPartFormatter::process(Inter
return MessagePart::Ptr();
}
- KMime::Content *dataHtml = findTypeInDirectChilds(node, "text/html");
- KMime::Content *dataPlain = findTypeInDirectChilds(node, "text/plain");
-
- if (!dataHtml) {
- // If we didn't find the HTML part as the first child of the multipart/alternative, it might
- // be that this is a HTML message with images, and text/plain and multipart/related are the
- // immediate children of this multipart/alternative node.
- // In this case, the HTML node is a child of multipart/related.
- dataHtml = findTypeInDirectChilds(node, "multipart/related");
-
- // Still not found? Stupid apple mail actually puts the attachments inside of the
- // multipart/alternative, which is wrong. Therefore we also have to look for multipart/mixed
- // here.
- // Do this only when prefering HTML mail, though, since otherwise the attachments are hidden
- // when displaying plain text.
- if (!dataHtml && part.source()->htmlMail()) {
- dataHtml = findTypeInDirectChilds(node, "multipart/mixed");
- }
+ auto preferredMode = part.source()->preferredMode();
+ AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(part.objectTreeParser(), node, preferredMode));
+ if (mp->mChildNodes.isEmpty()) {
+ MimeMessagePart::Ptr _mp(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false));
+ return _mp;
}
- if (dataPlain || dataHtml) {
- AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(part.objectTreeParser(), dataPlain, dataHtml));
-
- if ((part.source()->htmlMail() && dataHtml) ||
- (dataHtml && dataPlain && dataPlain->body().isEmpty())) {
- if (dataPlain) {
- part.nodeHelper()->setNodeProcessed(dataPlain, false);
- }
- part.source()->setHtmlMode(Util::MultipartHtml);
- mp->setViewHtml(true);
- }
+ KMime::Content *dataIcal = mp->mChildNodes.contains(Util::MultipartIcal) ? mp->mChildNodes[Util::MultipartIcal] : Q_NULLPTR;
+ KMime::Content *dataHtml = mp->mChildNodes.contains(Util::MultipartHtml) ? mp->mChildNodes[Util::MultipartHtml] : Q_NULLPTR;
+ KMime::Content *dataPlain = mp->mChildNodes.contains(Util::MultipartPlain) ? mp->mChildNodes[Util::MultipartPlain] : Q_NULLPTR;
- if (!part.source()->htmlMail() && dataPlain) {
+ // Make sure that in default ical is preffered over html and plain text
+ if (dataIcal && ((preferredMode != Util::MultipartHtml && preferredMode != Util::MultipartPlain))) {
+ if (dataHtml) {
part.nodeHelper()->setNodeProcessed(dataHtml, false);
- part.source()->setHtmlMode(Util::MultipartPlain);
- mp->setViewHtml(false);
}
- return mp;
+ if (dataPlain) {
+ part.nodeHelper()->setNodeProcessed(dataPlain, false);
+ }
+ preferredMode = Util::MultipartIcal;
+ } else if ((dataHtml && (preferredMode == Util::MultipartHtml || preferredMode == Util::Html)) ||
+ (dataHtml && dataPlain && dataPlain->body().isEmpty())) {
+ if (dataPlain) {
+ part.nodeHelper()->setNodeProcessed(dataPlain, false);
+ }
+ preferredMode = Util::MultipartHtml;
+ } else if (!(preferredMode == Util::MultipartHtml) && dataPlain) {
+ part.nodeHelper()->setNodeProcessed(dataHtml, false);
+ preferredMode = Util::MultipartPlain;
}
-
- MimeMessagePart::Ptr mp(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false));
+ part.source()->setHtmlMode(preferredMode, mp->availableModes());
+ mp->mPreferredMode = preferredMode;
return mp;
}
diff --git a/mimetreeparser/src/interfaces/objecttreesource.h b/mimetreeparser/src/interfaces/objecttreesource.h
index 3c1b0a8..efcf786 100644
--- a/mimetreeparser/src/interfaces/objecttreesource.h
+++ b/mimetreeparser/src/interfaces/objecttreesource.h
@@ -62,13 +62,12 @@ public:
* information to the user, for example KMail displays a HTML status bar.
* Note: This is not called when the mode is "Normal".
*/
- virtual void setHtmlMode(MimeTreeParser::Util::HtmlMode mode) = 0;
+ virtual void setHtmlMode(MimeTreeParser::Util::HtmlMode mode, const QList<MimeTreeParser::Util::HtmlMode> &availableModes) = 0;
- /** Return true if the mail should be parsed as a html mail */
- virtual bool htmlMail() const = 0;
+ /** Return the mode that is the preferred to display */
+ virtual MimeTreeParser::Util::HtmlMode preferredMode() const = 0;
/** Return true if an encrypted mail should be decrypted */
-
virtual bool decryptMessage() const = 0;
/** Return true if external sources should be loaded in a html mail */
diff --git a/mimetreeparser/src/utils/util.h b/mimetreeparser/src/utils/util.h
index 75e4cbe..a5470a1 100644
--- a/mimetreeparser/src/utils/util.h
+++ b/mimetreeparser/src/utils/util.h
@@ -48,7 +48,8 @@ enum HtmlMode {
Normal, ///< A normal plaintext message, non-multipart
Html, ///< A HTML message, non-multipart
MultipartPlain, ///< A multipart/alternative message, the plain text part is currently displayed
- MultipartHtml ///< A multipart/altervative message, the HTML part is currently displayed
+ MultipartHtml, ///< A multipart/altervative message, the HTML part is currently displayed
+ MultipartIcal ///< A multipart/altervative message, the ICal part is currently displayed
};
bool MIMETREEPARSER_EXPORT isTypeBlacklisted(KMime::Content *node);
diff --git a/mimetreeparser/src/viewer/messagepart.cpp b/mimetreeparser/src/viewer/messagepart.cpp
index 6f06c88..b9747ba 100644
--- a/mimetreeparser/src/viewer/messagepart.cpp
+++ b/mimetreeparser/src/viewer/messagepart.cpp
@@ -29,6 +29,8 @@
#include "memento/verifydetachedbodypartmemento.h"
#include "memento/verifyopaquebodypartmemento.h"
+#include "bodyformatter/utils.h"
+
#include <KMime/Content>
#include <Libkleo/Dn>
@@ -383,6 +385,8 @@ IconType AttachmentMessagePart::asIcon() const
const AttachmentStrategy *const as = mOtp->attachmentStrategy();
const bool defaultHidden(as && as->defaultDisplay(mNode) == AttachmentStrategy::None);
const bool showOnlyOneMimePart(mOtp->showOnlyOneMimePart());
+ auto preferredMode = source()->preferredMode();
+ bool isHtmlPreferred = (preferredMode == Util::Html) || (preferredMode == Util::MultipartHtml);
QByteArray mediaType("text");
QByteArray subType("plain");
@@ -414,7 +418,7 @@ IconType AttachmentMessagePart::asIcon() const
}
return MimeTreeParser::NoIcon;
} else {
- if (isImage() && source()->htmlMail() &&
+ if (isImage() && isHtmlPreferred &&
mNode->parent() && mNode->parent()->contentType()->subType() == "related") {
return MimeTreeParser::IconInline;
}
@@ -438,6 +442,8 @@ bool AttachmentMessagePart::isHidden() const
const AttachmentStrategy *const as = mOtp->attachmentStrategy();
const bool defaultHidden(as && as->defaultDisplay(mNode) == AttachmentStrategy::None);
const bool showOnlyOneMimePart(mOtp->showOnlyOneMimePart());
+ auto preferredMode = source()->preferredMode();
+ bool isHtmlPreferred = (preferredMode == Util::Html) || (preferredMode == Util::MultipartHtml);
QByteArray mediaType("text");
QByteArray subType("plain");
@@ -467,7 +473,7 @@ bool AttachmentMessagePart::isHidden() const
if (isTextPart) {
hidden = defaultHidden && !showOnlyOneMimePart;
} else {
- if (isImage() && source()->htmlMail() &&
+ if (isImage() && isHtmlPreferred &&
mNode->parent() && mNode->parent()->contentType()->subType() == "related") {
hidden = true;
} else {
@@ -553,23 +559,51 @@ QString MimeMessagePart::htmlContent() const
//-----AlternativeMessagePart----------------------
-AlternativeMessagePart::AlternativeMessagePart(ObjectTreeParser *otp, KMime::Content *textNode, KMime::Content *htmlNode)
+AlternativeMessagePart::AlternativeMessagePart(ObjectTreeParser *otp, KMime::Content *node, Util::HtmlMode preferredMode)
: MessagePart(otp, QString())
- , mTextNode(textNode)
- , mHTMLNode(htmlNode)
- , mViewHtml(false)
-{
- if (!mTextNode && !mHTMLNode) {
- qCWarning(MIMETREEPARSER_LOG) << "not a valid nodes";
- return;
+ , mNode(node)
+ , mPreferredMode(preferredMode)
+{
+ KMime::Content *dataIcal = findTypeInDirectChilds(mNode, "text/calendar");
+ KMime::Content *dataHtml = findTypeInDirectChilds(mNode, "text/html");
+ KMime::Content *dataText = findTypeInDirectChilds(mNode, "text/plain");
+
+ if (!dataHtml) {
+ // If we didn't find the HTML part as the first child of the multipart/alternative, it might
+ // be that this is a HTML message with images, and text/plain and multipart/related are the
+ // immediate children of this multipart/alternative node.
+ // In this case, the HTML node is a child of multipart/related.
+ dataHtml = findTypeInDirectChilds(mNode, "multipart/related");
+
+ // Still not found? Stupid apple mail actually puts the attachments inside of the
+ // multipart/alternative, which is wrong. Therefore we also have to look for multipart/mixed
+ // here.
+ // Do this only when prefering HTML mail, though, since otherwise the attachments are hidden
+ // when displaying plain text.
+ if (!dataHtml && mPreferredMode == Util::MultipartHtml) {
+ dataHtml = findTypeInDirectChilds(mNode, "multipart/mixed");
+ }
+ }
+
+ if (dataIcal) {
+ mChildNodes[Util::MultipartIcal] = dataIcal;
+ }
+
+ if (dataText) {
+ mChildNodes[Util::MultipartPlain] = dataText;
}
- if (mTextNode) {
- mTextPart = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, mTextNode, true));
+ if (dataHtml) {
+ mChildNodes[Util::MultipartHtml] = dataHtml;
+ }
+
+ if (mChildNodes.isEmpty()) {
+ qCWarning(MIMETREEPARSER_LOG) << "no valid nodes";
+ return;
}
- if (mHTMLNode) {
- mHTMLPart = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, mHTMLNode, true));
+ foreach(const auto name, mChildNodes.keys()) {
+ mChildParts[name] = MimeMessagePart::Ptr(new MimeMessagePart(mOtp, mChildNodes[name], true));
}
}
@@ -578,60 +612,62 @@ AlternativeMessagePart::~AlternativeMessagePart()
}
-void AlternativeMessagePart::setViewHtml(bool html)
+Util::HtmlMode AlternativeMessagePart::preferredMode() const
{
- mViewHtml = html;
+ return mPreferredMode;
}
-bool AlternativeMessagePart::viewHtml() const
+QList<Util::HtmlMode> AlternativeMessagePart::availableModes()
{
- return mViewHtml;
+ return mChildParts.keys();
}
QString AlternativeMessagePart::text() const
{
- if (mTextPart) {
- return mTextPart->text();
+ if (mChildParts.contains(Util::MultipartPlain)) {
+ return mChildParts[Util::MultipartPlain]->text();
}
return QString();
}
void AlternativeMessagePart::fix() const
{
- if (mTextPart) {
- mTextPart->fix();
+ if (mChildParts.contains(Util::MultipartPlain)) {
+ mChildParts[Util::MultipartPlain]->fix();
}
- if (viewHtml() && mHTMLPart) {
- mHTMLPart->fix();
+ const auto mode = preferredMode();
+ if (mode != Util::MultipartPlain && mChildParts.contains(mode)) {
+ //mChildParts[mode]->fix();
}
}
void AlternativeMessagePart::copyContentFrom() const
{
- if (mTextPart) {
- mTextPart->copyContentFrom();
+ if (mChildParts.contains(Util::MultipartPlain)) {
+ mChildParts[Util::MultipartPlain]->copyContentFrom();
}
- if (viewHtml() && mHTMLPart) {
- mHTMLPart->copyContentFrom();
+ const auto mode = preferredMode();
+ if (mode != Util::MultipartPlain && mChildParts.contains(mode)) {
+ mChildParts[mode]->copyContentFrom();
}
}
bool AlternativeMessagePart::isHtml() const
{
- return (mHTMLNode);
+ return mChildParts.contains(Util::MultipartHtml);
}
QString AlternativeMessagePart::plaintextContent() const
{
- return mTextPart->text();
+ return text();
}
QString AlternativeMessagePart::htmlContent() const
{
- if (mHTMLNode) {
- return mHTMLPart->text();
+ if (mChildParts.contains(Util::MultipartHtml)) {
+ return mChildParts[Util::MultipartHtml]->text();
} else {
return plaintextContent();
}
diff --git a/mimetreeparser/src/viewer/messagepart.h b/mimetreeparser/src/viewer/messagepart.h
index a33d864..e054476 100644
--- a/mimetreeparser/src/viewer/messagepart.h
+++ b/mimetreeparser/src/viewer/messagepart.h
@@ -23,6 +23,8 @@
#include "mimetreeparser_export.h"
#include "mimetreeparser/bodypartformatter.h"
+#include "mimetreeparser/util.h"
+
#include <KMime/Message>
#include <Libkleo/CryptoBackend>
@@ -52,7 +54,7 @@ class HtmlWriter;
class HTMLBlock;
typedef QSharedPointer<HTMLBlock> HTMLBlockPtr;
class CryptoBodyPartMemento;
-
+class MultiPartAlternativeBodyPartFormatter;
namespace Interface
{
class ObjectTreeSource;
@@ -237,31 +239,33 @@ class MIMETREEPARSER_EXPORT AlternativeMessagePart : public MessagePart
Q_OBJECT
public:
typedef QSharedPointer<AlternativeMessagePart> Ptr;
- AlternativeMessagePart(MimeTreeParser::ObjectTreeParser *otp, KMime::Content *textNode, KMime::Content *htmlNode);
+ AlternativeMessagePart(MimeTreeParser::ObjectTreeParser* otp, KMime::Content* node, Util::HtmlMode preferredMode);
virtual ~AlternativeMessagePart();
QString text() const Q_DECL_OVERRIDE;
- void setViewHtml(bool html);
- bool viewHtml() const;
+ Util::HtmlMode preferredMode() const;
bool isHtml() const Q_DECL_OVERRIDE;
QString plaintextContent() const Q_DECL_OVERRIDE;
QString htmlContent() const Q_DECL_OVERRIDE;
+ QList<Util::HtmlMode> availableModes();
+
void fix() const Q_DECL_OVERRIDE;
void copyContentFrom() const Q_DECL_OVERRIDE;
private:
- KMime::Content *mTextNode;
- KMime::Content *mHTMLNode;
+ KMime::Content *mNode;
+
+ Util::HtmlMode mPreferredMode;
- MimeMessagePart::Ptr mTextPart;
- MimeMessagePart::Ptr mHTMLPart;
- bool mViewHtml;
+ QMap<Util::HtmlMode, KMime::Content *> mChildNodes;
+ QMap<Util::HtmlMode, MimeMessagePart::Ptr> mChildParts;
friend class DefaultRendererPrivate;
friend class ObjectTreeParser;
+ friend class MultiPartAlternativeBodyPartFormatter;
};
class MIMETREEPARSER_EXPORT CertMessagePart : public MessagePart
diff --git a/mimetreeparser/src/viewer/objecttreeparser.cpp b/mimetreeparser/src/viewer/objecttreeparser.cpp
index 66b006a..d17c508 100644
--- a/mimetreeparser/src/viewer/objecttreeparser.cpp
+++ b/mimetreeparser/src/viewer/objecttreeparser.cpp
@@ -186,8 +186,8 @@ void ObjectTreeParser::parseObjectTree(KMime::Content *node)
if (auto _mp = mp.dynamicCast<TextMessagePart>()) {
extractNodeInfos(_mp->mNode, true);
} else if (auto _mp = mp.dynamicCast<AlternativeMessagePart>()) {
- if (_mp->mTextNode) {
- extractNodeInfos(_mp->mTextNode, true);
+ if (_mp->mChildNodes.contains(Util::MultipartPlain)) {
+ extractNodeInfos(_mp->mChildNodes[Util::MultipartPlain], true);
}
}
setPlainTextContent(mp->text());
@@ -369,8 +369,10 @@ Interface::MessagePart::Ptr ObjectTreeParser::defaultHandling(KMime::Content *no
mp = _mp;
// always show images in multipart/related when showing in html, not with an additional icon
+ auto preferredMode = mSource->preferredMode();
+ bool isHtmlPreferred = (preferredMode == Util::Html) || (preferredMode == Util::MultipartHtml);
if (result.isImage() && node->parent() &&
- node->parent()->contentType()->subType() == "related" && mSource->htmlMail() && !onlyOneMimePart) {
+ node->parent()->contentType()->subType() == "related" && isHtmlPreferred && !onlyOneMimePart) {
QString fileName = mNodeHelper->writeNodeToTempFile(node);
QString href = QUrl::fromLocalFile(fileName).url();
QByteArray cid = node->contentID()->identifier();