summaryrefslogtreecommitdiffstats
path: root/framework/src
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src')
-rw-r--r--framework/src/domain/mime/mailtemplates.cpp1
-rw-r--r--framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp133
-rw-r--r--framework/src/domain/mime/mimetreeparser/objecttreeparser.h20
-rw-r--r--framework/src/domain/mime/tests/mailtemplatetest.cpp4
4 files changed, 71 insertions, 87 deletions
diff --git a/framework/src/domain/mime/mailtemplates.cpp b/framework/src/domain/mime/mailtemplates.cpp
index c202af80..6d02124d 100644
--- a/framework/src/domain/mime/mailtemplates.cpp
+++ b/framework/src/domain/mime/mailtemplates.cpp
@@ -842,6 +842,7 @@ void MailTemplates::reply(const KMime::Message::Ptr &origMsg, const std::functio
842 842
843 MimeTreeParser::ObjectTreeParser otp; 843 MimeTreeParser::ObjectTreeParser otp;
844 otp.parseObjectTree(origMsg.data()); 844 otp.parseObjectTree(origMsg.data());
845 otp.decryptParts();
845 const auto plainTextContent = otp.plainTextContent(); 846 const auto plainTextContent = otp.plainTextContent();
846 const auto htmlContent = otp.htmlContent(); 847 const auto htmlContent = otp.htmlContent();
847 848
diff --git a/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp b/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp
index 0c3f60aa..7e2be0e4 100644
--- a/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp
+++ b/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp
@@ -60,6 +60,32 @@
60 60
61using namespace MimeTreeParser; 61using namespace MimeTreeParser;
62 62
63/*
64 * Collect message parts bottom up.
65 * Filter to avoid evaluating a subtree.
66 * Select parts to include it in the result set. Selecting a part in a branch will keep any parent parts from being selected.
67 */
68static QVector<MessagePart::Ptr> collect(MessagePart::Ptr start, const std::function<bool(const MessagePartPtr &)> &evaluateSubtree, const std::function<bool(const MessagePartPtr &)> &select)
69{
70 MessagePartPtr ptr = start.dynamicCast<MessagePart>();
71 Q_ASSERT(ptr);
72 QVector<MessagePart::Ptr> list;
73 if (evaluateSubtree(ptr)) {
74 for (const auto &p: ptr->subParts()) {
75 list << ::collect(p, evaluateSubtree, select);
76 }
77 }
78
79 //Don't consider this part if we already selected a subpart
80 if (list.isEmpty()) {
81 if (select(ptr)) {
82 list << start;
83 }
84 }
85 return list;
86}
87
88
63 89
64ObjectTreeParser::ObjectTreeParser() 90ObjectTreeParser::ObjectTreeParser()
65 : mNodeHelper(nullptr), 91 : mNodeHelper(nullptr),
@@ -96,14 +122,46 @@ ObjectTreeParser::~ObjectTreeParser()
96 } 122 }
97} 123}
98 124
99QString ObjectTreeParser::plainTextContent() const 125QString ObjectTreeParser::plainTextContent()
100{ 126{
101 return mPlainTextContent; 127 QString content;
128 if (mParsedPart) {
129 auto plainParts = ::collect(mParsedPart,
130 [] (const MessagePartPtr &part) {
131 return true;
132 },
133 [] (const MessagePartPtr &part) {
134 if (dynamic_cast<MimeTreeParser::TextMessagePart*>(part.data())) {
135 return true;
136 }
137 return false;
138 });
139 for (const auto &part : plainParts) {
140 content += part->text();
141 }
142 }
143 return content;
102} 144}
103 145
104QString ObjectTreeParser::htmlContent() const 146QString ObjectTreeParser::htmlContent()
105{ 147{
106 return mHtmlContent; 148 QString content;
149 if (mParsedPart) {
150 QVector<MessagePart::Ptr> contentParts = ::collect(mParsedPart,
151 [] (const MessagePartPtr &part) {
152 return true;
153 },
154 [] (const MessagePartPtr &part) {
155 if (dynamic_cast<MimeTreeParser::HtmlMessagePart*>(part.data())) {
156 return true;
157 }
158 return false;
159 });
160 for (const auto &part : contentParts) {
161 content += part->text();
162 }
163 }
164 return content;
107} 165}
108 166
109static void print(KMime::Content *node, const QString prefix = {}) 167static void print(KMime::Content *node, const QString prefix = {})
@@ -165,31 +223,6 @@ KMime::Content *ObjectTreeParser::find(const std::function<bool(KMime::Content *
165 return ::find(mTopLevelContent, select); 223 return ::find(mTopLevelContent, select);
166} 224}
167 225
168/*
169 * Collect message parts bottom up.
170 * Filter to avoid evaluating a subtree.
171 * Select parts to include it in the result set. Selecting a part in a branch will keep any parent parts from being selected.
172 */
173static QVector<MessagePart::Ptr> collect(MessagePart::Ptr start, const std::function<bool(const MessagePartPtr &)> &evaluateSubtree, const std::function<bool(const MessagePartPtr &)> &select)
174{
175 MessagePartPtr ptr = start.dynamicCast<MessagePart>();
176 Q_ASSERT(ptr);
177 QVector<MessagePart::Ptr> list;
178 if (evaluateSubtree(ptr)) {
179 for (const auto &p: ptr->subParts()) {
180 list << ::collect(p, evaluateSubtree, select);
181 }
182 }
183
184 //Don't consider this part if we already selected a subpart
185 if (list.isEmpty()) {
186 if (select(ptr)) {
187 list << start;
188 }
189 }
190 return list;
191}
192
193QVector<MessagePartPtr> ObjectTreeParser::collectContentParts() 226QVector<MessagePartPtr> ObjectTreeParser::collectContentParts()
194{ 227{
195 return collectContentParts(mParsedPart); 228 return collectContentParts(mParsedPart);
@@ -341,38 +374,6 @@ void ObjectTreeParser::parseObjectTree(KMime::Content *node)
341{ 374{
342 mTopLevelContent = node; 375 mTopLevelContent = node;
343 mParsedPart = parseObjectTreeInternal(node, showOnlyOneMimePart()); 376 mParsedPart = parseObjectTreeInternal(node, showOnlyOneMimePart());
344
345 //Gather plaintext and html content
346 if (mParsedPart) {
347 //Find relevant plaintext parts and set plaintext
348 if (auto mp = toplevelTextNode(mParsedPart)) {
349 if (auto _mp = mp.dynamicCast<TextMessagePart>()) {
350 mPlainTextContent += _mp->mNode->decodedText();
351 mPlainTextContentCharset += NodeHelper::charset(_mp->mNode);
352 } else if (auto _mp = mp.dynamicCast<AlternativeMessagePart>()) {
353 if (_mp->mChildNodes.contains(Util::MultipartPlain)) {
354 mPlainTextContent += _mp->mChildNodes[Util::MultipartPlain]->decodedText();
355 mPlainTextContentCharset += NodeHelper::charset(_mp->mChildNodes[Util::MultipartPlain]);
356 }
357 }
358 }
359
360 //Find html parts and copy content
361 QVector<MessagePart::Ptr> contentParts = ::collect(mParsedPart,
362 [] (const MessagePartPtr &part) {
363 return true;
364 },
365 [] (const MessagePartPtr &part) {
366 if (dynamic_cast<MimeTreeParser::HtmlMessagePart*>(part.data())) {
367 return true;
368 }
369 return false;
370 });
371 for (const auto &part : contentParts) {
372 mHtmlContent += part->text();
373 mHtmlContentCharset = part->charset();
374 }
375 }
376} 377}
377 378
378MessagePartPtr ObjectTreeParser::parsedPart() const 379MessagePartPtr ObjectTreeParser::parsedPart() const
@@ -487,16 +488,6 @@ const QTextCodec *ObjectTreeParser::codecFor(KMime::Content *node) const
487 return mNodeHelper->codec(node); 488 return mNodeHelper->codec(node);
488} 489}
489 490
490QByteArray ObjectTreeParser::plainTextContentCharset() const
491{
492 return mPlainTextContentCharset;
493}
494
495QByteArray ObjectTreeParser::htmlContentCharset() const
496{
497 return mHtmlContentCharset;
498}
499
500bool ObjectTreeParser::showOnlyOneMimePart() const 491bool ObjectTreeParser::showOnlyOneMimePart() const
501{ 492{
502 return mShowOnlyOneMimePart; 493 return mShowOnlyOneMimePart;
diff --git a/framework/src/domain/mime/mimetreeparser/objecttreeparser.h b/framework/src/domain/mime/mimetreeparser/objecttreeparser.h
index 9a3f5a5c..d2076be4 100644
--- a/framework/src/domain/mime/mimetreeparser/objecttreeparser.h
+++ b/framework/src/domain/mime/mimetreeparser/objecttreeparser.h
@@ -250,24 +250,12 @@ public:
250 * composer's text editor if this was edited or replied to. 250 * composer's text editor if this was edited or replied to.
251 * This is usually the content of the first text/plain MIME part. 251 * This is usually the content of the first text/plain MIME part.
252 */ 252 */
253 QString plainTextContent() const; 253 QString plainTextContent();
254 254
255 /** 255 /**
256 * Similar to plainTextContent(), but returns the HTML source of the first text/html MIME part. 256 * Similar to plainTextContent(), but returns the HTML source of the first text/html MIME part.
257 *
258 * Not to be consfused with the HTML code that the message viewer widget displays, that HTML
259 * is written out by htmlWriter() and a totally different pair of shoes.
260 */ 257 */
261 QString htmlContent() const; 258 QString htmlContent();
262
263 /**
264 * The original charset of MIME part the plain text was extracted from.
265 *
266 * If there were more than one text/plain MIME parts in the mail, the this is the charset
267 * of the last MIME part processed.
268 */
269 QByteArray plainTextContentCharset() const;
270 QByteArray htmlContentCharset() const;
271 259
272 bool showOnlyOneMimePart() const; 260 bool showOnlyOneMimePart() const;
273 void setShowOnlyOneMimePart(bool show); 261 void setShowOnlyOneMimePart(bool show);
@@ -283,7 +271,11 @@ public:
283 QVector<MessagePartPtr> collectContentParts(); 271 QVector<MessagePartPtr> collectContentParts();
284 QVector<MessagePartPtr> collectContentParts(MessagePart::Ptr start); 272 QVector<MessagePartPtr> collectContentParts(MessagePart::Ptr start);
285 QVector<MessagePartPtr> collectAttachmentParts(); 273 QVector<MessagePartPtr> collectAttachmentParts();
274
275 /** Decrypt parts and verify signatures */
286 void decryptParts(); 276 void decryptParts();
277
278 /** Import any certificates found in the message */
287 void importCertificates(); 279 void importCertificates();
288 280
289 /** Embedd content referenced by cid by inlining */ 281 /** Embedd content referenced by cid by inlining */
diff --git a/framework/src/domain/mime/tests/mailtemplatetest.cpp b/framework/src/domain/mime/tests/mailtemplatetest.cpp
index 18f315f1..4dc8e2bd 100644
--- a/framework/src/domain/mime/tests/mailtemplatetest.cpp
+++ b/framework/src/domain/mime/tests/mailtemplatetest.cpp
@@ -36,6 +36,7 @@ static QString normalize(const QString &s)
36 auto text = s; 36 auto text = s;
37 text.replace(">", ""); 37 text.replace(">", "");
38 text.replace("\n", ""); 38 text.replace("\n", "");
39 text.replace("=", "");
39 text.replace(" ", ""); 40 text.replace(" ", "");
40 return text; 41 return text;
41} 42}
@@ -87,9 +88,8 @@ private slots:
87 result = r; 88 result = r;
88 }); 89 });
89 QTRY_VERIFY(result); 90 QTRY_VERIFY(result);
90 auto content = normalize(removeFirstLine(result->body())); 91 auto content = removeFirstLine(result->body());
91 QVERIFY(!content.isEmpty()); 92 QVERIFY(!content.isEmpty());
92 QEXPECT_FAIL("", "Not implemented yet.", Continue);
93 QVERIFY(content.contains("i noticed a new branch")); 93 QVERIFY(content.contains("i noticed a new branch"));
94 } 94 }
95 95