diff options
author | Sandro Knauß <sknauss@kde.org> | 2016-10-11 16:18:50 +0200 |
---|---|---|
committer | Sandro Knauß <sknauss@kde.org> | 2016-10-11 16:18:50 +0200 |
commit | 1974c19eadd497e355ac985a00d0571f3e6c7712 (patch) | |
tree | 051b61cfe222150dc114e5da04fdd072ceffb3b7 /framework/domain | |
parent | 6b6f20ffbe06402abcc7d4721ad1f647c3fc4c46 (diff) | |
download | kube-1974c19eadd497e355ac985a00d0571f3e6c7712.tar.gz kube-1974c19eadd497e355ac985a00d0571f3e6c7712.zip |
create model for new mailviewer
Diffstat (limited to 'framework/domain')
-rw-r--r-- | framework/domain/CMakeLists.txt | 2 | ||||
-rw-r--r-- | framework/domain/messageparser.cpp | 123 | ||||
-rw-r--r-- | framework/domain/messageparser.h | 57 | ||||
-rw-r--r-- | framework/domain/messageparser_new.cpp | 148 | ||||
-rw-r--r-- | framework/domain/messageparser_old.cpp | 140 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/CMakeLists.txt | 5 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/interface.cpp | 14 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/interface.h | 2 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/tests/data/openpgp-inline-encrypted+nonenc.mbox | 31 | ||||
-rw-r--r-- | framework/domain/mimetreeparser/tests/interfacetest.cpp | 27 |
10 files changed, 426 insertions, 123 deletions
diff --git a/framework/domain/CMakeLists.txt b/framework/domain/CMakeLists.txt index 07f01367..c41da377 100644 --- a/framework/domain/CMakeLists.txt +++ b/framework/domain/CMakeLists.txt | |||
@@ -7,6 +7,8 @@ set(mailplugin_SRCS | |||
7 | stringhtmlwriter.cpp | 7 | stringhtmlwriter.cpp |
8 | composercontroller.cpp | 8 | composercontroller.cpp |
9 | messageparser.cpp | 9 | messageparser.cpp |
10 | messageparser_new.cpp | ||
11 | messageparser_old.cpp | ||
10 | mailtemplates.cpp | 12 | mailtemplates.cpp |
11 | retriever.cpp | 13 | retriever.cpp |
12 | accountfactory.cpp | 14 | accountfactory.cpp |
diff --git a/framework/domain/messageparser.cpp b/framework/domain/messageparser.cpp index febd1363..ef9fb0d2 100644 --- a/framework/domain/messageparser.cpp +++ b/framework/domain/messageparser.cpp | |||
@@ -33,125 +33,6 @@ | |||
33 | #include <MimeTreeParser/ObjectTreeParser> | 33 | #include <MimeTreeParser/ObjectTreeParser> |
34 | #include <MimeTreeParser/MessagePart> | 34 | #include <MimeTreeParser/MessagePart> |
35 | 35 | ||
36 | PartModel::PartModel(QSharedPointer<MimeTreeParser::MessagePart> partTree, std::shared_ptr<Parser> parser) | ||
37 | : mPartTree(partTree) | ||
38 | , mParser(parser) | ||
39 | { | ||
40 | } | ||
41 | |||
42 | QHash<int, QByteArray> PartModel::roleNames() const | ||
43 | { | ||
44 | QHash<int, QByteArray> roles; | ||
45 | roles[Text] = "text"; | ||
46 | roles[IsHtml] = "isHtml"; | ||
47 | roles[IsHidden] = "isHidden"; | ||
48 | roles[IsEncrypted] = "isEncrypted"; | ||
49 | roles[IsAttachment] = "isAttachment"; | ||
50 | roles[HasContent] = "hasContent"; | ||
51 | roles[Type] = "type"; | ||
52 | roles[IsHidden] = "isHidden"; | ||
53 | return roles; | ||
54 | } | ||
55 | |||
56 | QModelIndex PartModel::index(int row, int column, const QModelIndex &parent) const | ||
57 | { | ||
58 | // qDebug() << "index " << parent << row << column << mPartTree->subParts().size(); | ||
59 | if (!parent.isValid()) { | ||
60 | if (row < mPartTree->subParts().size()) { | ||
61 | auto part = mPartTree->subParts().at(row); | ||
62 | return createIndex(row, column, part.data()); | ||
63 | } | ||
64 | } else { | ||
65 | auto part = static_cast<MimeTreeParser::MessagePart*>(parent.internalPointer()); | ||
66 | auto subPart = part->subParts().at(row); | ||
67 | return createIndex(row, column, subPart.data()); | ||
68 | } | ||
69 | return QModelIndex(); | ||
70 | } | ||
71 | |||
72 | QVariant PartModel::data(const QModelIndex &index, int role) const | ||
73 | { | ||
74 | // qDebug() << "Getting data for index"; | ||
75 | if (index.isValid()) { | ||
76 | auto part = static_cast<MimeTreeParser::MessagePart*>(index.internalPointer()); | ||
77 | switch (role) { | ||
78 | case Text: { | ||
79 | // qDebug() << "Getting text: " << part->property("text").toString(); | ||
80 | // FIXME: we should have a list per part, and not one for all parts. | ||
81 | auto text = part->property("htmlContent").toString(); | ||
82 | auto rx = QRegExp("src=(\"|')cid:([^\1]*)\1"); | ||
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(); | ||
90 | } | ||
91 | return text; | ||
92 | } | ||
93 | case IsAttachment: | ||
94 | return part->property("attachment").toBool(); | ||
95 | case IsEncrypted: | ||
96 | return part->property("isEncrypted").toBool(); | ||
97 | case IsHtml: | ||
98 | return part->property("isHtml").toBool(); | ||
99 | case HasContent: | ||
100 | return !part->property("htmlContent").toString().isEmpty(); | ||
101 | case Type: | ||
102 | return part->metaObject()->className(); | ||
103 | case IsHidden: | ||
104 | return false; | ||
105 | //return part->property("isHidden").toBool(); | ||
106 | |||
107 | } | ||
108 | } | ||
109 | return QVariant(); | ||
110 | } | ||
111 | |||
112 | QModelIndex PartModel::parent(const QModelIndex &index) const | ||
113 | { | ||
114 | // qDebug() << "parent " << index; | ||
115 | if (index.isValid()) { | ||
116 | auto part = static_cast<MimeTreeParser::MessagePart*>(index.internalPointer()); | ||
117 | auto parentPart = static_cast<MimeTreeParser::MessagePart*>(part->parentPart()); | ||
118 | auto row = 0;//get the parents parent to find the index | ||
119 | if (!parentPart) { | ||
120 | parentPart = mPartTree.data(); | ||
121 | } | ||
122 | int i = 0; | ||
123 | for (const auto &p : parentPart->subParts()) { | ||
124 | if (p.data() == part) { | ||
125 | row = i; | ||
126 | break; | ||
127 | } | ||
128 | i++; | ||
129 | } | ||
130 | return createIndex(row, index.column(), parentPart); | ||
131 | } | ||
132 | return QModelIndex(); | ||
133 | } | ||
134 | |||
135 | int PartModel::rowCount(const QModelIndex &parent) const | ||
136 | { | ||
137 | // qDebug() << "Row count " << parent; | ||
138 | if (!parent.isValid()) { | ||
139 | // qDebug() << "Row count " << mPartTree->subParts().size(); | ||
140 | return mPartTree->subParts().size(); | ||
141 | } else { | ||
142 | auto part = static_cast<MimeTreeParser::MessagePart*>(parent.internalPointer()); | ||
143 | if (part) { | ||
144 | return part->subParts().size(); | ||
145 | } | ||
146 | } | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | int PartModel::columnCount(const QModelIndex &parent) const | ||
151 | { | ||
152 | // qDebug() << "Column count " << parent; | ||
153 | return 1; | ||
154 | } | ||
155 | 36 | ||
156 | class MessagePartPrivate | 37 | class MessagePartPrivate |
157 | { | 38 | { |
@@ -217,3 +98,7 @@ QAbstractItemModel *MessageParser::partTree() const | |||
217 | return new PartModel(d->mPartTree, d->mParser); | 98 | return new PartModel(d->mPartTree, d->mParser); |
218 | } | 99 | } |
219 | 100 | ||
101 | QAbstractItemModel *MessageParser::newTree() const | ||
102 | { | ||
103 | return new NewModel(d->mParser); | ||
104 | } | ||
diff --git a/framework/domain/messageparser.h b/framework/domain/messageparser.h index 9469f2b5..b3d7537d 100644 --- a/framework/domain/messageparser.h +++ b/framework/domain/messageparser.h | |||
@@ -32,6 +32,10 @@ | |||
32 | class QAbstractItemModel; | 32 | class QAbstractItemModel; |
33 | 33 | ||
34 | class Parser; | 34 | class Parser; |
35 | class Part; | ||
36 | typedef std::shared_ptr<Part> PartPtr; | ||
37 | class Content; | ||
38 | typedef std::shared_ptr<Content> ContentPtr; | ||
35 | class MessagePartPrivate; | 39 | class MessagePartPrivate; |
36 | 40 | ||
37 | class MessageParser : public QObject | 41 | class MessageParser : public QObject |
@@ -40,6 +44,7 @@ class MessageParser : public QObject | |||
40 | Q_PROPERTY (QVariant message READ message WRITE setMessage) | 44 | Q_PROPERTY (QVariant message READ message WRITE setMessage) |
41 | Q_PROPERTY (QString html READ html NOTIFY htmlChanged) | 45 | Q_PROPERTY (QString html READ html NOTIFY htmlChanged) |
42 | Q_PROPERTY (QAbstractItemModel* partTree READ partTree NOTIFY htmlChanged) | 46 | Q_PROPERTY (QAbstractItemModel* partTree READ partTree NOTIFY htmlChanged) |
47 | Q_PROPERTY (QAbstractItemModel* newTree READ newTree NOTIFY htmlChanged) | ||
43 | 48 | ||
44 | public: | 49 | public: |
45 | explicit MessageParser(QObject *parent = Q_NULLPTR); | 50 | explicit MessageParser(QObject *parent = Q_NULLPTR); |
@@ -50,6 +55,7 @@ public: | |||
50 | QVariant message() const; | 55 | QVariant message() const; |
51 | void setMessage(const QVariant &to); | 56 | void setMessage(const QVariant &to); |
52 | QAbstractItemModel *partTree() const; | 57 | QAbstractItemModel *partTree() const; |
58 | QAbstractItemModel *newTree() const; | ||
53 | 59 | ||
54 | signals: | 60 | signals: |
55 | void htmlChanged(); | 61 | void htmlChanged(); |
@@ -87,3 +93,54 @@ private: | |||
87 | std::shared_ptr<Parser> mParser; | 93 | std::shared_ptr<Parser> mParser; |
88 | }; | 94 | }; |
89 | 95 | ||
96 | |||
97 | class NewContentModel : public QAbstractItemModel { | ||
98 | Q_OBJECT | ||
99 | public: | ||
100 | NewContentModel (const PartPtr &part); | ||
101 | |||
102 | public: | ||
103 | enum Roles { | ||
104 | TypeRole = Qt::UserRole + 1, | ||
105 | ContentRole, | ||
106 | IsEmbededRole, | ||
107 | SecurityLevelRole | ||
108 | }; | ||
109 | |||
110 | QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE; | ||
111 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; | ||
112 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; | ||
113 | QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; | ||
114 | int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; | ||
115 | int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; | ||
116 | |||
117 | private: | ||
118 | const PartPtr &mPart; | ||
119 | }; | ||
120 | |||
121 | class NewModel : public QAbstractItemModel { | ||
122 | Q_OBJECT | ||
123 | public: | ||
124 | NewModel(std::shared_ptr<Parser> parser); | ||
125 | |||
126 | public: | ||
127 | enum Roles { | ||
128 | TypeRole = Qt::UserRole + 1, | ||
129 | ContentsRole, | ||
130 | IsEmbededRole, | ||
131 | SecurityLevelRole | ||
132 | }; | ||
133 | |||
134 | QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE; | ||
135 | QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; | ||
136 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; | ||
137 | QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; | ||
138 | int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; | ||
139 | int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; | ||
140 | |||
141 | private: | ||
142 | std::shared_ptr<Parser> mParser; | ||
143 | QVector<PartPtr> mParts; | ||
144 | QMap<Part *, std::shared_ptr<NewContentModel>> mContentMap; | ||
145 | }; | ||
146 | |||
diff --git a/framework/domain/messageparser_new.cpp b/framework/domain/messageparser_new.cpp new file mode 100644 index 00000000..d1b956f5 --- /dev/null +++ b/framework/domain/messageparser_new.cpp | |||
@@ -0,0 +1,148 @@ | |||
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 | |||
24 | NewModel::NewModel(std::shared_ptr<Parser> parser) | ||
25 | : mParser(parser) | ||
26 | { | ||
27 | mParts = mParser->collectContentParts(); | ||
28 | foreach(const auto &part, mParts) { | ||
29 | mContentMap.insert(part.get(), std::shared_ptr<NewContentModel>(new NewContentModel(part))); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | QHash<int, QByteArray> NewModel::roleNames() const | ||
34 | { | ||
35 | QHash<int, QByteArray> roles; | ||
36 | roles[TypeRole] = "type"; | ||
37 | roles[ContentsRole] = "contents"; | ||
38 | roles[IsEmbededRole] = "embeded"; | ||
39 | roles[SecurityLevelRole] = "securityLevel"; | ||
40 | return roles; | ||
41 | } | ||
42 | |||
43 | QModelIndex NewModel::index(int row, int column, const QModelIndex &parent) const | ||
44 | { | ||
45 | if (!parent.isValid()) { | ||
46 | if (row < mParts.size()) { | ||
47 | auto part = mParts.at(row); | ||
48 | return createIndex(row, column, part.get()); | ||
49 | } | ||
50 | } | ||
51 | return QModelIndex(); | ||
52 | } | ||
53 | |||
54 | QVariant NewModel::data(const QModelIndex &index, int role) const | ||
55 | { | ||
56 | if (!index.parent().isValid()) { | ||
57 | auto part = static_cast<Part *>(index.internalPointer()); | ||
58 | switch (role) { | ||
59 | case TypeRole: | ||
60 | return QString::fromLatin1(part->type()); | ||
61 | case IsEmbededRole: | ||
62 | return index.parent().isValid(); | ||
63 | case SecurityLevelRole: | ||
64 | return QStringLiteral("GRAY"); | ||
65 | case ContentsRole: | ||
66 | return QVariant::fromValue<QAbstractItemModel *>(mContentMap.value(part).get()); | ||
67 | } | ||
68 | } | ||
69 | return QVariant(); | ||
70 | } | ||
71 | |||
72 | QModelIndex NewModel::parent(const QModelIndex &index) const | ||
73 | { | ||
74 | return QModelIndex(); | ||
75 | } | ||
76 | |||
77 | int NewModel::rowCount(const QModelIndex &parent) const | ||
78 | { | ||
79 | if (!parent.isValid()) { | ||
80 | return mParts.size(); | ||
81 | } | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | int NewModel::columnCount(const QModelIndex &parent) const | ||
86 | { | ||
87 | return 1; | ||
88 | } | ||
89 | |||
90 | NewContentModel::NewContentModel(const Part::Ptr &part) | ||
91 | : mPart(part) | ||
92 | { | ||
93 | } | ||
94 | |||
95 | QHash<int, QByteArray> NewContentModel::roleNames() const | ||
96 | { | ||
97 | QHash<int, QByteArray> roles; | ||
98 | roles[TypeRole] = "type"; | ||
99 | roles[ContentRole] = "content"; | ||
100 | roles[IsEmbededRole] = "embeded"; | ||
101 | roles[SecurityLevelRole] = "securityLevel"; | ||
102 | return roles; | ||
103 | } | ||
104 | |||
105 | QModelIndex NewContentModel::index(int row, int column, const QModelIndex &parent) const | ||
106 | { | ||
107 | if (!parent.isValid()) { | ||
108 | if (row < mPart->content().size()) { | ||
109 | auto part = mPart->content().at(row); | ||
110 | return createIndex(row, column, part.get()); | ||
111 | } | ||
112 | } | ||
113 | return QModelIndex(); | ||
114 | } | ||
115 | |||
116 | QVariant NewContentModel::data(const QModelIndex &index, int role) const | ||
117 | { | ||
118 | auto content = static_cast<Content *>(index.internalPointer()); | ||
119 | switch (role) { | ||
120 | case TypeRole: | ||
121 | return QString::fromLatin1(content->type()); | ||
122 | case IsEmbededRole: | ||
123 | return false; | ||
124 | case ContentRole: | ||
125 | return content->encodedContent(); | ||
126 | case SecurityLevelRole: | ||
127 | return content->encryptions().size() > mPart->encryptions().size() ? "red": "black"; //test for gpg inline | ||
128 | } | ||
129 | return QVariant(); | ||
130 | } | ||
131 | |||
132 | QModelIndex NewContentModel::parent(const QModelIndex &index) const | ||
133 | { | ||
134 | return QModelIndex(); | ||
135 | } | ||
136 | |||
137 | int NewContentModel::rowCount(const QModelIndex &parent) const | ||
138 | { | ||
139 | if (!parent.isValid()) { | ||
140 | return mPart->content().size(); | ||
141 | } | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | int NewContentModel::columnCount(const QModelIndex &parent) const | ||
146 | { | ||
147 | return 1; | ||
148 | } | ||
diff --git a/framework/domain/messageparser_old.cpp b/framework/domain/messageparser_old.cpp new file mode 100644 index 00000000..a364c8ab --- /dev/null +++ b/framework/domain/messageparser_old.cpp | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | This library is free software; you can redistribute it and/or modify it | ||
3 | under the terms of the GNU Library General Public License as published by | ||
4 | the Free Software Foundation; either version 2 of the License, or (at your | ||
5 | option) any later version. | ||
6 | |||
7 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
8 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
9 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
10 | License for more details. | ||
11 | |||
12 | You should have received a copy of the GNU Library General Public License | ||
13 | along with this library; see the file COPYING.LIB. If not, write to the | ||
14 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
15 | 02110-1301, USA. | ||
16 | */ | ||
17 | |||
18 | #include "messageparser.h" | ||
19 | #include "mimetreeparser/interface.h" | ||
20 | |||
21 | PartModel::PartModel(QSharedPointer<MimeTreeParser::MessagePart> partTree, std::shared_ptr<Parser> parser) | ||
22 | : mPartTree(partTree) | ||
23 | , mParser(parser) | ||
24 | { | ||
25 | } | ||
26 | |||
27 | QHash<int, QByteArray> PartModel::roleNames() const | ||
28 | { | ||
29 | QHash<int, QByteArray> roles; | ||
30 | roles[Text] = "text"; | ||
31 | roles[IsHtml] = "isHtml"; | ||
32 | roles[IsHidden] = "isHidden"; | ||
33 | roles[IsEncrypted] = "isEncrypted"; | ||
34 | roles[IsAttachment] = "isAttachment"; | ||
35 | roles[HasContent] = "hasContent"; | ||
36 | roles[Type] = "type"; | ||
37 | roles[IsHidden] = "isHidden"; | ||
38 | return roles; | ||
39 | } | ||
40 | |||
41 | QModelIndex PartModel::index(int row, int column, const QModelIndex &parent) const | ||
42 | { | ||
43 | // qDebug() << "index " << parent << row << column << mPartTree->subParts().size(); | ||
44 | if (!parent.isValid()) { | ||
45 | if (row < mPartTree->subParts().size()) { | ||
46 | auto part = mPartTree->subParts().at(row); | ||
47 | return createIndex(row, column, part.data()); | ||
48 | } | ||
49 | } else { | ||
50 | auto part = static_cast<MimeTreeParser::MessagePart*>(parent.internalPointer()); | ||
51 | auto subPart = part->subParts().at(row); | ||
52 | return createIndex(row, column, subPart.data()); | ||
53 | } | ||
54 | return QModelIndex(); | ||
55 | } | ||
56 | |||
57 | QVariant PartModel::data(const QModelIndex &index, int role) const | ||
58 | { | ||
59 | // qDebug() << "Getting data for index"; | ||
60 | if (index.isValid()) { | ||
61 | auto part = static_cast<MimeTreeParser::MessagePart*>(index.internalPointer()); | ||
62 | switch (role) { | ||
63 | case Text: { | ||
64 | // qDebug() << "Getting text: " << part->property("text").toString(); | ||
65 | // FIXME: we should have a list per part, and not one for all parts. | ||
66 | auto text = part->property("htmlContent").toString(); | ||
67 | auto rx = QRegExp("src=(\"|')cid:([^\1]*)\1"); | ||
68 | int pos = 0; | ||
69 | while ((pos = rx.indexIn(text, pos)) != -1) { | ||
70 | auto repl = mParser->getPart(rx.cap(2).toUtf8()); | ||
71 | if (repl.isValid()) { | ||
72 | text.replace(rx.cap(0), QString("src=\"%1\"").arg(repl.toString())); | ||
73 | } | ||
74 | pos += rx.matchedLength(); | ||
75 | } | ||
76 | return text; | ||
77 | } | ||
78 | case IsAttachment: | ||
79 | return part->property("attachment").toBool(); | ||
80 | case IsEncrypted: | ||
81 | return part->property("isEncrypted").toBool(); | ||
82 | case IsHtml: | ||
83 | return part->property("isHtml").toBool(); | ||
84 | case HasContent: | ||
85 | return !part->property("htmlContent").toString().isEmpty(); | ||
86 | case Type: | ||
87 | return part->metaObject()->className(); | ||
88 | case IsHidden: | ||
89 | return false; | ||
90 | //return part->property("isHidden").toBool(); | ||
91 | |||
92 | } | ||
93 | } | ||
94 | return QVariant(); | ||
95 | } | ||
96 | |||
97 | QModelIndex PartModel::parent(const QModelIndex &index) const | ||
98 | { | ||
99 | // qDebug() << "parent " << index; | ||
100 | if (index.isValid()) { | ||
101 | auto part = static_cast<MimeTreeParser::MessagePart*>(index.internalPointer()); | ||
102 | auto parentPart = static_cast<MimeTreeParser::MessagePart*>(part->parentPart()); | ||
103 | auto row = 0;//get the parents parent to find the index | ||
104 | if (!parentPart) { | ||
105 | parentPart = mPartTree.data(); | ||
106 | } | ||
107 | int i = 0; | ||
108 | for (const auto &p : parentPart->subParts()) { | ||
109 | if (p.data() == part) { | ||
110 | row = i; | ||
111 | break; | ||
112 | } | ||
113 | i++; | ||
114 | } | ||
115 | return createIndex(row, index.column(), parentPart); | ||
116 | } | ||
117 | return QModelIndex(); | ||
118 | } | ||
119 | |||
120 | int PartModel::rowCount(const QModelIndex &parent) const | ||
121 | { | ||
122 | // qDebug() << "Row count " << parent; | ||
123 | if (!parent.isValid()) { | ||
124 | // qDebug() << "Row count " << mPartTree->subParts().size(); | ||
125 | return mPartTree->subParts().size(); | ||
126 | } else { | ||
127 | auto part = static_cast<MimeTreeParser::MessagePart*>(parent.internalPointer()); | ||
128 | if (part) { | ||
129 | return part->subParts().size(); | ||
130 | } | ||
131 | } | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | int PartModel::columnCount(const QModelIndex &parent) const | ||
136 | { | ||
137 | // qDebug() << "Column count " << parent; | ||
138 | return 1; | ||
139 | } | ||
140 | |||
diff --git a/framework/domain/mimetreeparser/CMakeLists.txt b/framework/domain/mimetreeparser/CMakeLists.txt index e1c04893..64da2656 100644 --- a/framework/domain/mimetreeparser/CMakeLists.txt +++ b/framework/domain/mimetreeparser/CMakeLists.txt | |||
@@ -9,4 +9,7 @@ add_library(mimetreeparser SHARED ${mimetreeparser_SRCS}) | |||
9 | qt5_use_modules(mimetreeparser Core Gui) | 9 | qt5_use_modules(mimetreeparser Core Gui) |
10 | target_link_libraries(mimetreeparser KF5::Mime KF5::MimeTreeParser) | 10 | target_link_libraries(mimetreeparser KF5::Mime KF5::MimeTreeParser) |
11 | 11 | ||
12 | add_subdirectory(tests) \ No newline at end of file | 12 | install(TARGETS mimetreeparser |
13 | DESTINATION ${LIB_INSTALL_DIR}) | ||
14 | |||
15 | add_subdirectory(tests) | ||
diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index c3ecf79c..efa0fd40 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <QMimeDatabase> | 31 | #include <QMimeDatabase> |
32 | #include <QMimeType> | 32 | #include <QMimeType> |
33 | #include <QTextCodec> | ||
33 | #include <QDebug> | 34 | #include <QDebug> |
34 | 35 | ||
35 | class MailMimePrivate | 36 | class MailMimePrivate |
@@ -356,6 +357,17 @@ QByteArray Content::charset() const | |||
356 | return d->mCodec; | 357 | return d->mCodec; |
357 | } | 358 | } |
358 | 359 | ||
360 | QString Content::encodedContent() const | ||
361 | { | ||
362 | return encodedContent(charset()); | ||
363 | } | ||
364 | |||
365 | QString Content::encodedContent(const QByteArray &charset) const | ||
366 | { | ||
367 | QTextCodec *codec = QTextCodec::codecForName(charset); | ||
368 | return codec->toUnicode(content()); | ||
369 | } | ||
370 | |||
359 | QByteArray Content::type() const | 371 | QByteArray Content::type() const |
360 | { | 372 | { |
361 | return "Content"; | 373 | return "Content"; |
@@ -496,7 +508,7 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) | |||
496 | mContent.clear(); | 508 | mContent.clear(); |
497 | foreach (const auto &mp, part->subParts()) { | 509 | foreach (const auto &mp, part->subParts()) { |
498 | auto d_ptr = new ContentPrivate; | 510 | auto d_ptr = new ContentPrivate; |
499 | d_ptr->mContent = part->text().toLocal8Bit(); | 511 | d_ptr->mContent = mp->text().toLocal8Bit(); |
500 | d_ptr->mParent = q; | 512 | d_ptr->mParent = q; |
501 | d_ptr->mCodec = "utf-8"; | 513 | d_ptr->mCodec = "utf-8"; |
502 | const auto enc = mp.dynamicCast<MimeTreeParser::EncryptedMessagePart>(); | 514 | const auto enc = mp.dynamicCast<MimeTreeParser::EncryptedMessagePart>(); |
diff --git a/framework/domain/mimetreeparser/interface.h b/framework/domain/mimetreeparser/interface.h index 7eadc311..67246f37 100644 --- a/framework/domain/mimetreeparser/interface.h +++ b/framework/domain/mimetreeparser/interface.h | |||
@@ -125,7 +125,7 @@ public: | |||
125 | QString encodedContent() const; | 125 | QString encodedContent() const; |
126 | 126 | ||
127 | // overwrite default charset with given charset | 127 | // overwrite default charset with given charset |
128 | QString encodedContent(QByteArray charset) const; | 128 | QString encodedContent(const QByteArray &charset) const; |
129 | 129 | ||
130 | QVector<SignaturePtr> signatures() const; | 130 | QVector<SignaturePtr> signatures() const; |
131 | QVector<EncryptionPtr> encryptions() const; | 131 | QVector<EncryptionPtr> encryptions() const; |
diff --git a/framework/domain/mimetreeparser/tests/data/openpgp-inline-encrypted+nonenc.mbox b/framework/domain/mimetreeparser/tests/data/openpgp-inline-encrypted+nonenc.mbox new file mode 100644 index 00000000..b98dc336 --- /dev/null +++ b/framework/domain/mimetreeparser/tests/data/openpgp-inline-encrypted+nonenc.mbox | |||
@@ -0,0 +1,31 @@ | |||
1 | From test@kolab.org Wed, 25 May 2011 23:49:40 +0100 | ||
2 | From: OpenPGP Test <test@kolab.org> | ||
3 | To: test@kolab.org | ||
4 | Subject: inlinepgpencrypted + non enc text | ||
5 | Date: Wed, 25 May 2011 23:49:40 +0100 | ||
6 | Message-ID: <1786696.yKXrOjjflF@herrwackelpudding.localhost> | ||
7 | X-KMail-Transport: GMX | ||
8 | X-KMail-Fcc: 28 | ||
9 | X-KMail-Drafts: 7 | ||
10 | X-KMail-Templates: 9 | ||
11 | User-Agent: KMail/4.6 beta5 (Linux/2.6.34.7-0.7-desktop; KDE/4.6.41; x86_64; git-0269848; 2011-04-19) | ||
12 | MIME-Version: 1.0 | ||
13 | Content-Transfer-Encoding: 7Bit | ||
14 | Content-Type: text/plain; charset="us-ascii" | ||
15 | |||
16 | Not encrypted not signed :( | ||
17 | |||
18 | -----BEGIN PGP MESSAGE----- | ||
19 | Version: GnuPG v2.0.15 (GNU/Linux) | ||
20 | |||
21 | hQEMAwzOQ1qnzNo7AQf/a3aNTLpQBfcUr+4AKsZQLj4h6z7e7a5AaCW8AG0wrbxN | ||
22 | kBYB7E5jdZh45DX/99gvoZslthWryUCX2kKZ3LtIllxKVjqNuK5hSt+SAuKkwiMR | ||
23 | Xcbf1KFKENKupgGSO9B2NJRbjoExdJ+fC3mGXnO3dT7xJJAo3oLE8Nivu+Bj1peY | ||
24 | E1wCf+vcTwVHFrA7SV8eMRb9Z9wBXmU8Q8e9ekJ7ZsRX3tMeBs6jvscVvfMf6DYY | ||
25 | N14snZBZuGNKT9a3DPny7IC1S0lHcaam34ogWwMi3FxPGJt/Lg52kARlkF5TDhcP | ||
26 | N6H0EB/iqDRjOOUoEVm8um5XOSR1FpEiAdD0DON3y9JPATnrYq7sgYZz3BVImYY+ | ||
27 | N/jV8fEiN0a34pcOq8NQedMuOsJHNBS5MtbQH/kJLq0MXBpXekGlHo4MKw0trISc | ||
28 | Rw3pW6/BFfhPJLni29g9tw== | ||
29 | =fRFW | ||
30 | -----END PGP MESSAGE----- | ||
31 | |||
diff --git a/framework/domain/mimetreeparser/tests/interfacetest.cpp b/framework/domain/mimetreeparser/tests/interfacetest.cpp index ac77b025..5a3cbb87 100644 --- a/framework/domain/mimetreeparser/tests/interfacetest.cpp +++ b/framework/domain/mimetreeparser/tests/interfacetest.cpp | |||
@@ -198,7 +198,32 @@ private slots: | |||
198 | auto contentAttachmentList = parser.collectAttachmentParts(); | 198 | auto contentAttachmentList = parser.collectAttachmentParts(); |
199 | QCOMPARE(contentAttachmentList.size(), 0); | 199 | QCOMPARE(contentAttachmentList.size(), 0); |
200 | } | 200 | } |
201 | |||
202 | void testOpenPPGInlineWithNonEncText() | ||
203 | { | ||
204 | Parser parser(readMailFromFile("openpgp-inline-encrypted+nonenc.mbox")); | ||
205 | printTree(parser.d->mTree,QString()); | ||
206 | auto contentPartList = parser.collectContentParts(); | ||
207 | QCOMPARE(contentPartList.size(), 1); | ||
208 | auto contentPart = contentPartList[0]; | ||
209 | QVERIFY((bool)contentPart); | ||
210 | QCOMPARE(contentPart->availableContents(), QVector<QByteArray>() << "plaintext"); | ||
211 | QCOMPARE(contentPart->encryptions().size(), 0); | ||
212 | QCOMPARE(contentPart->signatures().size(), 0); | ||
213 | auto contentList = contentPart->content("plaintext"); | ||
214 | QCOMPARE(contentList.size(), 2); | ||
215 | QCOMPARE(contentList[0]->content(), QStringLiteral("Not encrypted not signed :(\n\n").toLocal8Bit()); | ||
216 | QCOMPARE(contentList[0]->charset(), QStringLiteral("utf-8").toLocal8Bit()); | ||
217 | QCOMPARE(contentList[0]->encryptions().size(), 0); | ||
218 | QCOMPARE(contentList[0]->signatures().size(), 0); | ||
219 | QCOMPARE(contentList[1]->content(), QStringLiteral("some random text").toLocal8Bit()); | ||
220 | QCOMPARE(contentList[1]->charset(), QStringLiteral("utf-8").toLocal8Bit()); | ||
221 | QCOMPARE(contentList[1]->encryptions().size(), 1); | ||
222 | QCOMPARE(contentList[1]->signatures().size(), 0); | ||
223 | auto contentAttachmentList = parser.collectAttachmentParts(); | ||
224 | QCOMPARE(contentAttachmentList.size(), 0); | ||
225 | } | ||
201 | }; | 226 | }; |
202 | 227 | ||
203 | QTEST_GUILESS_MAIN(InterfaceTest) | 228 | QTEST_GUILESS_MAIN(InterfaceTest) |
204 | #include "interfacetest.moc" \ No newline at end of file | 229 | #include "interfacetest.moc" |