summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp')
-rw-r--r--framework/src/domain/mime/mimetreeparser/objecttreeparser.cpp133
1 files changed, 62 insertions, 71 deletions
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;