diff options
-rw-r--r-- | framework/domain/CMakeLists.txt | 2 | ||||
-rw-r--r-- | framework/domain/messageparser.cpp | 49 | ||||
-rw-r--r-- | framework/domain/messageparser.h | 15 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/interface.cpp | 5 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/interface.h | 2 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/interface_p.h | 1 |
6 files changed, 54 insertions, 20 deletions
diff --git a/framework/domain/CMakeLists.txt b/framework/domain/CMakeLists.txt index 92a81352..07f01367 100644 --- a/framework/domain/CMakeLists.txt +++ b/framework/domain/CMakeLists.txt | |||
@@ -20,7 +20,7 @@ find_package(KF5 REQUIRED COMPONENTS Package) | |||
20 | add_library(mailplugin SHARED ${mailplugin_SRCS}) | 20 | add_library(mailplugin SHARED ${mailplugin_SRCS}) |
21 | 21 | ||
22 | qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) | 22 | qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) |
23 | target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package KF5::Async KF5::IconThemes) | 23 | target_link_libraries(mailplugin actionplugin settingsplugin sink mimetreeparser KF5::MimeTreeParser KF5::Codecs KF5::Package KF5::Async KF5::IconThemes) |
24 | 24 | ||
25 | add_subdirectory(actions/tests) | 25 | add_subdirectory(actions/tests) |
26 | 26 | ||
diff --git a/framework/domain/messageparser.cpp b/framework/domain/messageparser.cpp index 8363e119..262be0b7 100644 --- a/framework/domain/messageparser.cpp +++ b/framework/domain/messageparser.cpp | |||
@@ -21,6 +21,10 @@ | |||
21 | #include "stringhtmlwriter.h" | 21 | #include "stringhtmlwriter.h" |
22 | #include "objecttreesource.h" | 22 | #include "objecttreesource.h" |
23 | 23 | ||
24 | #include "mimetreeparser/interface.h" | ||
25 | |||
26 | #include <QRegExp> | ||
27 | |||
24 | #include <QFile> | 28 | #include <QFile> |
25 | #include <QImage> | 29 | #include <QImage> |
26 | #include <QDebug> | 30 | #include <QDebug> |
@@ -29,7 +33,9 @@ | |||
29 | #include <MimeTreeParser/ObjectTreeParser> | 33 | #include <MimeTreeParser/ObjectTreeParser> |
30 | #include <MimeTreeParser/MessagePart> | 34 | #include <MimeTreeParser/MessagePart> |
31 | 35 | ||
32 | PartModel::PartModel(QSharedPointer<MimeTreeParser::MessagePart> partTree, QMap<QByteArray, QUrl> embeddedPartMap) : mPartTree(partTree), mEmbeddedPartMap(embeddedPartMap) | 36 | PartModel::PartModel(QSharedPointer<MimeTreeParser::MessagePart> partTree, std::shared_ptr<Parser> parser) |
37 | : mPartTree(partTree) | ||
38 | , mParser(parser) | ||
33 | { | 39 | { |
34 | } | 40 | } |
35 | 41 | ||
@@ -73,8 +79,14 @@ QVariant PartModel::data(const QModelIndex &index, int role) const | |||
73 | // qDebug() << "Getting text: " << part->property("text").toString(); | 79 | // qDebug() << "Getting text: " << part->property("text").toString(); |
74 | // FIXME: we should have a list per part, and not one for all parts. | 80 | // FIXME: we should have a list per part, and not one for all parts. |
75 | auto text = part->property("htmlContent").toString(); | 81 | auto text = part->property("htmlContent").toString(); |
76 | for (const auto &cid : mEmbeddedPartMap.keys()) { | 82 | auto rx = QRegExp("src=(\"|')cid:([^\1]*)\1"); |
77 | text.replace(QString("src=\"cid:%1\"").arg(QString(cid)), QString("src=\"%1\"").arg(mEmbeddedPartMap.value(cid).toString())); | 83 | int pos = 0; |
84 | while ((pos = rx.indexIn(text, pos)) != -1) { | ||
85 | auto repl = mParser->getPart(rx.cap(2).toUtf8()); | ||
86 | if (repl.isValid()) { | ||
87 | text.replace(rx.cap(0), QString("src=\"%1\"").arg(repl.toString())); | ||
88 | } | ||
89 | pos += rx.matchedLength(); | ||
78 | } | 90 | } |
79 | return text; | 91 | return text; |
80 | } | 92 | } |
@@ -140,16 +152,31 @@ int PartModel::columnCount(const QModelIndex &parent) const | |||
140 | return 1; | 152 | return 1; |
141 | } | 153 | } |
142 | 154 | ||
155 | class MessagePartPrivate | ||
156 | { | ||
157 | public: | ||
158 | QSharedPointer<MimeTreeParser::MessagePart> mPartTree; | ||
159 | QString mHtml; | ||
160 | QMap<QByteArray, QUrl> mEmbeddedPartMap; | ||
161 | std::shared_ptr<MimeTreeParser::NodeHelper> mNodeHelper; | ||
162 | std::shared_ptr<Parser> mParser; | ||
163 | }; | ||
143 | 164 | ||
144 | MessageParser::MessageParser(QObject *parent) | 165 | MessageParser::MessageParser(QObject *parent) |
145 | : QObject(parent) | 166 | : QObject(parent) |
167 | , d(std::unique_ptr<MessagePartPrivate>(new MessagePartPrivate)) | ||
168 | { | ||
169 | |||
170 | } | ||
171 | |||
172 | MessageParser::~MessageParser() | ||
146 | { | 173 | { |
147 | 174 | ||
148 | } | 175 | } |
149 | 176 | ||
150 | QString MessageParser::html() const | 177 | QString MessageParser::html() const |
151 | { | 178 | { |
152 | return mHtml; | 179 | return d->mHtml; |
153 | } | 180 | } |
154 | 181 | ||
155 | QVariant MessageParser::message() const | 182 | QVariant MessageParser::message() const |
@@ -161,6 +188,8 @@ void MessageParser::setMessage(const QVariant &message) | |||
161 | { | 188 | { |
162 | QTime time; | 189 | QTime time; |
163 | time.start(); | 190 | time.start(); |
191 | d->mParser = std::shared_ptr<Parser>(new Parser(message.toByteArray())); | ||
192 | |||
164 | const auto mailData = KMime::CRLFtoLF(message.toByteArray()); | 193 | const auto mailData = KMime::CRLFtoLF(message.toByteArray()); |
165 | KMime::Message::Ptr msg(new KMime::Message); | 194 | KMime::Message::Ptr msg(new KMime::Message); |
166 | msg->setContent(mailData); | 195 | msg->setContent(mailData); |
@@ -170,20 +199,20 @@ void MessageParser::setMessage(const QVariant &message) | |||
170 | // render the mail | 199 | // render the mail |
171 | StringHtmlWriter htmlWriter; | 200 | StringHtmlWriter htmlWriter; |
172 | //temporary files only have the lifetime of the nodehelper, so we keep it around until the mail changes. | 201 | //temporary files only have the lifetime of the nodehelper, so we keep it around until the mail changes. |
173 | mNodeHelper = std::make_shared<MimeTreeParser::NodeHelper>(); | 202 | d->mNodeHelper = std::make_shared<MimeTreeParser::NodeHelper>(); |
174 | ObjectTreeSource source(&htmlWriter); | 203 | ObjectTreeSource source(&htmlWriter); |
175 | MimeTreeParser::ObjectTreeParser otp(&source, mNodeHelper.get()); | 204 | MimeTreeParser::ObjectTreeParser otp(&source, d->mNodeHelper.get()); |
176 | 205 | ||
177 | otp.parseObjectTree(msg.data()); | 206 | otp.parseObjectTree(msg.data()); |
178 | mPartTree = otp.parsedPart().dynamicCast<MimeTreeParser::MessagePart>(); | 207 | d->mPartTree = otp.parsedPart().dynamicCast<MimeTreeParser::MessagePart>(); |
179 | 208 | ||
180 | mEmbeddedPartMap = htmlWriter.embeddedParts(); | 209 | d->mEmbeddedPartMap = htmlWriter.embeddedParts(); |
181 | mHtml = htmlWriter.html(); | 210 | d->mHtml = htmlWriter.html(); |
182 | emit htmlChanged(); | 211 | emit htmlChanged(); |
183 | } | 212 | } |
184 | 213 | ||
185 | QAbstractItemModel *MessageParser::partTree() const | 214 | QAbstractItemModel *MessageParser::partTree() const |
186 | { | 215 | { |
187 | return new PartModel(mPartTree, mEmbeddedPartMap); | 216 | return new PartModel(d->mPartTree, d->mParser); |
188 | } | 217 | } |
189 | 218 | ||
diff --git a/framework/domain/messageparser.h b/framework/domain/messageparser.h index 3e0255df..9469f2b5 100644 --- a/framework/domain/messageparser.h +++ b/framework/domain/messageparser.h | |||
@@ -29,11 +29,11 @@ | |||
29 | #include <memory> | 29 | #include <memory> |
30 | #include <MimeTreeParser/MessagePart> | 30 | #include <MimeTreeParser/MessagePart> |
31 | 31 | ||
32 | namespace MimeTreeParser { | ||
33 | class NodeHelper; | ||
34 | }; | ||
35 | class QAbstractItemModel; | 32 | class QAbstractItemModel; |
36 | 33 | ||
34 | class Parser; | ||
35 | class MessagePartPrivate; | ||
36 | |||
37 | class MessageParser : public QObject | 37 | class MessageParser : public QObject |
38 | { | 38 | { |
39 | Q_OBJECT | 39 | Q_OBJECT |
@@ -43,6 +43,7 @@ class MessageParser : public QObject | |||
43 | 43 | ||
44 | public: | 44 | public: |
45 | explicit MessageParser(QObject *parent = Q_NULLPTR); | 45 | explicit MessageParser(QObject *parent = Q_NULLPTR); |
46 | ~MessageParser(); | ||
46 | 47 | ||
47 | QString html() const; | 48 | QString html() const; |
48 | 49 | ||
@@ -54,16 +55,13 @@ signals: | |||
54 | void htmlChanged(); | 55 | void htmlChanged(); |
55 | 56 | ||
56 | private: | 57 | private: |
57 | QSharedPointer<MimeTreeParser::MessagePart> mPartTree; | 58 | std::unique_ptr<MessagePartPrivate> d; |
58 | QString mHtml; | ||
59 | QMap<QByteArray, QUrl> mEmbeddedPartMap; | ||
60 | std::shared_ptr<MimeTreeParser::NodeHelper> mNodeHelper; | ||
61 | }; | 59 | }; |
62 | 60 | ||
63 | class PartModel : public QAbstractItemModel { | 61 | class PartModel : public QAbstractItemModel { |
64 | Q_OBJECT | 62 | Q_OBJECT |
65 | public: | 63 | public: |
66 | PartModel(QSharedPointer<MimeTreeParser::MessagePart> partTree, QMap<QByteArray, QUrl> embeddedPartMap); | 64 | PartModel(QSharedPointer<MimeTreeParser::MessagePart> partTree, std::shared_ptr<Parser> parser); |
67 | 65 | ||
68 | public: | 66 | public: |
69 | enum Roles { | 67 | enum Roles { |
@@ -86,5 +84,6 @@ public: | |||
86 | private: | 84 | private: |
87 | QSharedPointer<MimeTreeParser::MessagePart> mPartTree; | 85 | QSharedPointer<MimeTreeParser::MessagePart> mPartTree; |
88 | QMap<QByteArray, QUrl> mEmbeddedPartMap; | 86 | QMap<QByteArray, QUrl> mEmbeddedPartMap; |
87 | std::shared_ptr<Parser> mParser; | ||
89 | }; | 88 | }; |
90 | 89 | ||
diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index d6354c9e..c3ecf79c 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp | |||
@@ -706,6 +706,11 @@ Parser::~Parser() | |||
706 | { | 706 | { |
707 | } | 707 | } |
708 | 708 | ||
709 | QUrl Parser::getPart(const QByteArray &cid) | ||
710 | { | ||
711 | return d->mEmbeddedPartMap.value(cid); | ||
712 | } | ||
713 | |||
709 | QVector<Part::Ptr> Parser::collectContentParts() const | 714 | QVector<Part::Ptr> Parser::collectContentParts() const |
710 | { | 715 | { |
711 | return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, | 716 | return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, |
diff --git a/framework/domain/mimetreeparser/interface.h b/framework/domain/mimetreeparser/interface.h index a482a824..7eadc311 100644 --- a/framework/domain/mimetreeparser/interface.h +++ b/framework/domain/mimetreeparser/interface.h | |||
@@ -181,6 +181,7 @@ public: | |||
181 | private: | 181 | private: |
182 | std::unique_ptr<CertContentPrivate> d; | 182 | std::unique_ptr<CertContentPrivate> d; |
183 | }; | 183 | }; |
184 | |||
184 | class Part | 185 | class Part |
185 | { | 186 | { |
186 | public: | 187 | public: |
@@ -346,6 +347,7 @@ public: | |||
346 | ~Parser(); | 347 | ~Parser(); |
347 | 348 | ||
348 | Part::Ptr getPart(QUrl url); | 349 | Part::Ptr getPart(QUrl url); |
350 | QUrl getPart(const QByteArray &cid); | ||
349 | 351 | ||
350 | QVector<Part::Ptr> collect(const Part::Ptr &start, std::function<bool(const Part::Ptr &)> select, std::function<bool(const Content::Ptr &)> filter) const; | 352 | QVector<Part::Ptr> collect(const Part::Ptr &start, std::function<bool(const Part::Ptr &)> select, std::function<bool(const Content::Ptr &)> filter) const; |
351 | QVector<Part::Ptr> collectContentParts() const; | 353 | QVector<Part::Ptr> collectContentParts() const; |
diff --git a/framework/domain/mimetreeparser/interface_p.h b/framework/domain/mimetreeparser/interface_p.h index 004a50d0..55d1a5cc 100644 --- a/framework/domain/mimetreeparser/interface_p.h +++ b/framework/domain/mimetreeparser/interface_p.h | |||
@@ -46,7 +46,6 @@ public: | |||
46 | void createTree(const MimeTreeParser::MessagePartPtr& start, const Part::Ptr& tree); | 46 | void createTree(const MimeTreeParser::MessagePartPtr& start, const Part::Ptr& tree); |
47 | 47 | ||
48 | Part::Ptr mTree; | 48 | Part::Ptr mTree; |
49 | private: | ||
50 | Parser *q; | 49 | Parser *q; |
51 | 50 | ||
52 | MimeTreeParser::MessagePartPtr mPartTree; | 51 | MimeTreeParser::MessagePartPtr mPartTree; |