summaryrefslogtreecommitdiffstats
path: root/framework/domain/messageparser_new.cpp
diff options
context:
space:
mode:
authorSandro Knauß <sknauss@kde.org>2016-10-24 13:02:40 +0200
committerSandro Knauß <sknauss@kde.org>2016-10-24 13:02:40 +0200
commit6aa695939b63fc7370e5eb80ecf7528aea1bd5e1 (patch)
tree91e7951411f541d7b71d64f15a2a38c6bbd7c577 /framework/domain/messageparser_new.cpp
parent9be2b6515cf538673babda8764219b9af9691f6f (diff)
parenta93a649f34ffa794884019e05c57869bd3bd4672 (diff)
downloadkube-6aa695939b63fc7370e5eb80ecf7528aea1bd5e1.tar.gz
kube-6aa695939b63fc7370e5eb80ecf7528aea1bd5e1.zip
Merge branch 'dev/mimetreeinterface' into develop
Diffstat (limited to 'framework/domain/messageparser_new.cpp')
-rw-r--r--framework/domain/messageparser_new.cpp457
1 files changed, 457 insertions, 0 deletions
diff --git a/framework/domain/messageparser_new.cpp b/framework/domain/messageparser_new.cpp
new file mode 100644
index 00000000..b930f33d
--- /dev/null
+++ b/framework/domain/messageparser_new.cpp
@@ -0,0 +1,457 @@
1
2/*
3 This library is free software; you can redistribute it and/or modify it
4 under the terms of the GNU Library General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This library is distributed in the hope that it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
11 License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to the
15 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 02110-1301, USA.
17*/
18
19#include "messageparser.h"
20#include "mimetreeparser/interface.h"
21
22#include <QDebug>
23
24Q_DECLARE_METATYPE(Part *)
25Q_DECLARE_METATYPE(Content *)
26Q_DECLARE_METATYPE(Signature *)
27Q_DECLARE_METATYPE(Encryption *)
28
29class Entry;
30
31class NewModelPrivate
32{
33public:
34 NewModelPrivate(NewModel *q_ptr, const std::shared_ptr<Parser> &parser);
35 ~NewModelPrivate();
36
37 void createTree();
38
39 QSharedPointer<QVariant> getVar(const std::shared_ptr<Signature> &sig);
40 QSharedPointer<QVariant> getVar(const std::shared_ptr<Encryption> &enc);
41 QSharedPointer<QVariant> getVar(const std::shared_ptr<Part> &part);
42 QSharedPointer<QVariant> getVar(Part *part);
43 QSharedPointer<QVariant> getVar(const std::shared_ptr<Content> &content);
44 QSharedPointer<QVariant> getVar(Content *content);
45
46 int getPos(Signature *sig);
47 int getPos(Encryption *enc);
48 int getPos(Part *part);
49 int getPos(Content *content);
50
51 NewModel *q;
52 QVector<Part::Ptr> mParts;
53 std::unique_ptr<Entry> mRoot;
54
55 std::shared_ptr<Parser> mParser;
56private:
57 QMap<std::shared_ptr<Signature>, QSharedPointer<QVariant>> mSignatureMap;
58 QMap<std::shared_ptr<Encryption>, QSharedPointer<QVariant>> mEncryptionMap;
59 QMap<Part *, QSharedPointer<QVariant>> mPartMap;
60 QMap<Content *, QSharedPointer<QVariant>> mCMap;
61};
62
63class Entry
64{
65public:
66 Entry(NewModelPrivate *model)
67 : mParent(nullptr)
68 , mNewModelPrivate(model)
69 {
70 }
71
72 ~Entry()
73 {
74 foreach(auto child, mChildren) {
75 delete child;
76 }
77 mChildren.clear();
78 }
79
80 void addChild(Entry *entry)
81 {
82 mChildren.append(entry);
83 entry->mParent = this;
84 }
85
86 Entry *addSignatures(QVector<Signature::Ptr> signatures)
87 {
88 auto ret = this;
89 foreach(const auto &sig, signatures) {
90 auto entry = new Entry(mNewModelPrivate);
91 entry->mData = mNewModelPrivate->getVar(sig);
92 ret->addChild(entry);
93 ret = entry;
94 }
95 return ret;
96 }
97
98 Entry *addEncryptions(QVector<Encryption::Ptr> encryptions)
99 {
100 auto ret = this;
101 foreach(const auto &enc, encryptions) {
102 auto entry = new Entry(mNewModelPrivate);
103 entry->mData = mNewModelPrivate->getVar(enc);
104 ret->addChild(entry);
105 ret = entry;
106 }
107 return ret;
108 }
109
110 Entry *addPart(Part *part)
111 {
112 auto entry = new Entry(mNewModelPrivate);
113 entry->mData = mNewModelPrivate->getVar(part);
114 addChild(entry);
115 foreach(const auto &content, part->content()) {
116 auto _entry = entry;
117 _entry = _entry->addEncryptions(content->encryptions().mid(part->encryptions().size()));
118 _entry = _entry->addSignatures(content->signatures().mid(part->signatures().size()));
119 auto c = new Entry(mNewModelPrivate);
120 c->mData = mNewModelPrivate->getVar(content);
121 _entry->addChild(c);
122 }
123 foreach(const auto &sp, part->subParts()) {
124 auto _entry = entry;
125 _entry = _entry->addEncryptions(sp->encryptions().mid(part->encryptions().size()));
126 _entry = _entry->addSignatures(sp->signatures().mid(part->signatures().size()));
127 _entry->addPart(sp.get());
128 }
129 return entry;
130 }
131
132 int pos()
133 {
134 if(!mParent) {
135 return -1;
136 }
137 int i=0;
138 foreach(const auto &child, mParent->mChildren) {
139 if (child == this) {
140 return i;
141 }
142 i++;
143 }
144 return -1;
145 }
146
147 QSharedPointer<QVariant> mData;
148
149 Entry *mParent;
150 QVector<Entry *> mChildren;
151 NewModelPrivate *mNewModelPrivate;
152};
153
154
155NewModelPrivate::NewModelPrivate(NewModel *q_ptr, const std::shared_ptr<Parser> &parser)
156 : q(q_ptr)
157 , mRoot(std::unique_ptr<Entry>(new Entry(this)))
158 , mParser(parser)
159{
160 mParts = mParser->collectContentParts();
161 createTree();
162}
163
164NewModelPrivate::~NewModelPrivate()
165{
166}
167
168void NewModelPrivate::createTree()
169{
170 auto root = mRoot.get();
171 auto parent = root;
172 Part *pPart = nullptr;
173 QVector<Signature::Ptr> signatures;
174 QVector<Encryption::Ptr> encryptions;
175 foreach(const auto part, mParts) {
176 auto _parent = parent;
177 if (pPart != part->parent()) {
178 auto _parent = root;
179 _parent = _parent->addEncryptions(part->parent()->encryptions());
180 _parent = _parent->addSignatures(part->parent()->signatures());
181 signatures = part->parent()->signatures();
182 encryptions = part->parent()->encryptions();
183 parent = _parent;
184 pPart = part->parent();
185 }
186 _parent = _parent->addEncryptions(part->encryptions().mid(encryptions.size()));
187 _parent = _parent->addSignatures(part->signatures().mid(signatures.size()));
188 _parent->addPart(part.get());
189 }
190}
191
192QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Signature> &sig)
193{
194 if (!mSignatureMap.contains(sig)) {
195 auto var = new QVariant();
196 var->setValue(sig.get());
197 mSignatureMap.insert(sig, QSharedPointer<QVariant>(var));
198 }
199 return mSignatureMap.value(sig);
200}
201
202QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Encryption> &enc)
203{
204 if (!mEncryptionMap.contains(enc)) {
205 auto var = new QVariant();
206 var->setValue(enc.get());
207 mEncryptionMap.insert(enc, QSharedPointer<QVariant>(var));
208 }
209 return mEncryptionMap.value(enc);
210}
211
212QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Part> &part)
213{
214 return getVar(part.get());
215}
216
217QSharedPointer<QVariant> NewModelPrivate::getVar(Part *part)
218{
219 if (!mPartMap.contains(part)) {
220 auto var = new QVariant();
221 var->setValue(part);
222 mPartMap.insert(part, QSharedPointer<QVariant>(var));
223 }
224 return mPartMap.value(part);
225}
226
227QSharedPointer<QVariant> NewModelPrivate::getVar(const std::shared_ptr<Content> &content)
228{
229 return getVar(content.get());
230}
231
232QSharedPointer<QVariant> NewModelPrivate::getVar(Content *content)
233{
234 if (!mCMap.contains(content)) {
235 auto var = new QVariant();
236 var->setValue(content);
237 mCMap.insert(content, QSharedPointer<QVariant>(var));
238 }
239 return mCMap.value(content);
240}
241
242int NewModelPrivate::getPos(Signature *signature)
243{
244 const auto first = mParts.first();
245 int i = 0;
246 foreach(const auto &sig, first->signatures()) {
247 if (sig.get() == signature) {
248 break;
249 }
250 i++;
251 }
252 return i;
253}
254
255int NewModelPrivate::getPos(Encryption *encryption)
256{
257 const auto first = mParts.first();
258 int i = 0;
259 foreach(const auto &enc, first->encryptions()) {
260 if (enc.get() == encryption) {
261 break;
262 }
263 i++;
264 }
265 return i;
266}
267
268int NewModelPrivate::getPos(Part *part)
269{
270 int i = 0;
271 foreach(const auto &p, mParts) {
272 if (p.get() == part) {
273 break;
274 }
275 i++;
276 }
277 return i;
278}
279
280int NewModelPrivate::getPos(Content *content)
281{
282 int i = 0;
283 foreach(const auto &c, content->parent()->content()) {
284 if (c.get() == content) {
285 break;
286 }
287 i++;
288 }
289 return i;
290}
291
292NewModel::NewModel(std::shared_ptr<Parser> parser)
293 : d(std::unique_ptr<NewModelPrivate>(new NewModelPrivate(this, parser)))
294{
295}
296
297NewModel::~NewModel()
298{
299}
300
301QHash<int, QByteArray> NewModel::roleNames() const
302{
303 QHash<int, QByteArray> roles;
304 roles[TypeRole] = "type";
305 roles[ContentRole] = "content";
306 roles[IsEmbededRole] = "embeded";
307 roles[SecurityLevelRole] = "securityLevel";
308 return roles;
309}
310
311QModelIndex NewModel::index(int row, int column, const QModelIndex &parent) const
312{
313 if (row < 0 || column != 0) {
314 return QModelIndex();
315 }
316 Entry *entry = d->mRoot.get();
317 if (parent.isValid()) {
318 entry = static_cast<Entry *>(parent.internalPointer());
319 }
320
321 if (row < entry->mChildren.size()) {
322 return createIndex(row, column, entry->mChildren.at(row));
323 }
324 return QModelIndex();
325}
326
327QVariant NewModel::data(const QModelIndex &index, int role) const
328{
329 if (!index.isValid()) {
330 switch (role) {
331 case Qt::DisplayRole:
332 return QString("root");
333 case IsEmbededRole:
334 return false;
335 }
336 return QVariant();
337 }
338
339 if (index.internalPointer()) {
340 const auto entry = static_cast<Entry *>(index.internalPointer());
341 const auto _data = entry->mData;
342 if (entry == d->mRoot.get()|| !_data) {
343 switch (role) {
344 case Qt::DisplayRole:
345 return QString("root");
346 case IsEmbededRole:
347 return false;
348 }
349 return QVariant();
350 }
351 if (_data->userType() == qMetaTypeId<Signature *>()) {
352 const auto signature = _data->value<Signature *>();
353 int i = d->getPos(signature);
354 switch(role) {
355 case Qt::DisplayRole:
356 return QStringLiteral("Signature%1").arg(i);
357 case TypeRole:
358 return QStringLiteral("Signature");
359 case SecurityLevelRole:
360 return QStringLiteral("RED");
361 case IsEmbededRole:
362 return data(index.parent(), IsEmbededRole);
363 }
364 } else if (_data->userType() == qMetaTypeId<Encryption *>()) {
365 const auto encryption = _data->value<Encryption *>();
366 int i = d->getPos(encryption);
367 switch(role) {
368 case Qt::DisplayRole:
369 return QStringLiteral("Encryption%1").arg(i);
370 case TypeRole:
371 return QStringLiteral("Encryption");
372 case SecurityLevelRole:
373 return QStringLiteral("GREEN");
374 case IsEmbededRole:
375 return data(index.parent(), IsEmbededRole);
376 }
377 } else if (_data->userType() == qMetaTypeId<Part *>()) {
378 const auto part = _data->value<Part *>();
379 switch (role) {
380 case Qt::DisplayRole:
381 case TypeRole:
382 return QString::fromLatin1(part->type());
383 case IsEmbededRole:
384 return data(index.parent(), IsEmbededRole);
385 }
386 } else if (_data->userType() == qMetaTypeId<Content *>()) {
387 const auto content = _data->value<Content *>();
388 int i = d->getPos(content);
389 switch(role) {
390 case Qt::DisplayRole:
391 return QStringLiteral("Content%1").arg(i);
392 case TypeRole:
393 return QString::fromLatin1(content->type());
394 case IsEmbededRole:
395 return data(index.parent(), IsEmbededRole);
396 case ContentRole: {
397 auto text = content->encodedContent();
398 if (data(index, TypeRole).toString() == "HtmlContent") {
399 const auto rx = QRegExp("(src)\\s*=\\s*(\"|')(cid:[^\"']+)\\2");
400 int pos = 0;
401 while ((pos = rx.indexIn(text, pos)) != -1) {
402 const auto link = QUrl(rx.cap(3).toUtf8());
403 pos += rx.matchedLength();
404 const auto repl = d->mParser->getPart(link);
405 if (!repl) {
406 continue;
407 }
408 const auto content = repl->content();
409 if(content.size() < 1) {
410 continue;
411 }
412 const auto mailMime = content.first()->mailMime();
413 const auto mimetype = mailMime->mimetype().name();
414 if (mimetype.startsWith("image/")) {
415 const auto data = content.first()->content();
416 text.replace(rx.cap(0), QString("src=\"data:%1;base64,%2\"").arg(mimetype, QString::fromLatin1(data.toBase64())));
417 }
418 }
419 }
420 return text;
421 }
422 }
423 }
424 }
425 return QVariant();
426}
427
428QModelIndex NewModel::parent(const QModelIndex &index) const
429{
430 if (!index.internalPointer()) {
431 return QModelIndex();
432 }
433 const auto entry = static_cast<Entry *>(index.internalPointer());
434 if (entry->mParent && entry->mParent != d->mRoot.get()) {
435 return createIndex(entry->pos(), 0, entry->mParent);
436 }
437 return QModelIndex();
438}
439
440int NewModel::rowCount(const QModelIndex &parent) const
441{
442 if (!parent.isValid()) {
443 return d->mRoot->mChildren.size();
444 } else {
445 if (!parent.internalPointer()) {
446 return 0;
447 }
448 const auto entry = static_cast<Entry *>(parent.internalPointer());
449 return entry->mChildren.size();
450 }
451 return 0;
452}
453
454int NewModel::columnCount(const QModelIndex &parent) const
455{
456 return 1;
457}