summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--framework/qml/MailViewer.qml4
-rw-r--r--framework/src/domain/mime/attachmentmodel.cpp38
-rw-r--r--framework/src/domain/mime/messageparser.h2
-rw-r--r--framework/src/domain/mime/mimetreeparser/interface.cpp16
-rw-r--r--framework/src/domain/mime/mimetreeparser/interface.h1
5 files changed, 60 insertions, 1 deletions
diff --git a/framework/qml/MailViewer.qml b/framework/qml/MailViewer.qml
index 73dcc291..d2c0a3be 100644
--- a/framework/qml/MailViewer.qml
+++ b/framework/qml/MailViewer.qml
@@ -288,6 +288,10 @@ Rectangle {
288 clip: true 288 clip: true
289 289
290 //TODO size encrypted signed type 290 //TODO size encrypted signed type
291 MouseArea {
292 anchors.fill: parent
293 onClicked: messageParser.attachments.saveAttachmentToDisk(messageParser.attachments.index(index, 0))
294 }
291 } 295 }
292 } 296 }
293 } 297 }
diff --git a/framework/src/domain/mime/attachmentmodel.cpp b/framework/src/domain/mime/attachmentmodel.cpp
index 2871579c..714177e1 100644
--- a/framework/src/domain/mime/attachmentmodel.cpp
+++ b/framework/src/domain/mime/attachmentmodel.cpp
@@ -20,8 +20,11 @@
20#include "messageparser.h" 20#include "messageparser.h"
21#include "mimetreeparser/interface.h" 21#include "mimetreeparser/interface.h"
22 22
23#include <QIcon>
24#include <QDebug> 23#include <QDebug>
24#include <KMime/Content>
25#include <QFile>
26#include <QStandardPaths>
27#include <QDir>
25 28
26QString sizeHuman(const Content::Ptr &content) 29QString sizeHuman(const Content::Ptr &content)
27{ 30{
@@ -126,6 +129,39 @@ QVariant AttachmentModel::data(const QModelIndex &index, int role) const
126 return QVariant(); 129 return QVariant();
127} 130}
128 131
132bool AttachmentModel::saveAttachmentToDisk(const QModelIndex &index)
133{
134 if (index.internalPointer()) {
135 const auto entry = static_cast<Part *>(index.internalPointer());
136 const auto content = entry->content().at(0);
137 auto filename = entry->mailMime()->filename();
138 auto data = content->mailMime()->decodedContent();
139
140 auto downloadDir = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
141 if (downloadDir.isEmpty()) {
142 downloadDir = "~";
143 }
144 downloadDir += "/kube/";
145 QDir{}.mkpath(downloadDir);
146
147 auto fname = downloadDir + filename;
148
149 if (content->mailMime()->isText() && !data.isEmpty()) {
150 // convert CRLF to LF before writing text attachments to disk
151 data = KMime::CRLFtoLF(data);
152 }
153 QFile f(fname);
154 if (!f.open(QIODevice::ReadWrite)) {
155 qWarning() << "Failed to write attachment to file:" << fname << " Error: " << f.errorString();
156 return false;
157 }
158 f.write(data);
159 qInfo() << "Wrote attachment to file: " << fname;
160 return true;
161 }
162 return false;
163}
164
129QModelIndex AttachmentModel::parent(const QModelIndex &index) const 165QModelIndex AttachmentModel::parent(const QModelIndex &index) const
130{ 166{
131 return QModelIndex(); 167 return QModelIndex();
diff --git a/framework/src/domain/mime/messageparser.h b/framework/src/domain/mime/messageparser.h
index de4d8838..1f44b296 100644
--- a/framework/src/domain/mime/messageparser.h
+++ b/framework/src/domain/mime/messageparser.h
@@ -111,6 +111,8 @@ public:
111 int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; 111 int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
112 int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; 112 int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
113 113
114 Q_INVOKABLE bool saveAttachmentToDisk(const QModelIndex &parent);
115
114private: 116private:
115 std::unique_ptr<AttachmentModelPrivate> d; 117 std::unique_ptr<AttachmentModelPrivate> d;
116}; 118};
diff --git a/framework/src/domain/mime/mimetreeparser/interface.cpp b/framework/src/domain/mime/mimetreeparser/interface.cpp
index b8556336..653789a5 100644
--- a/framework/src/domain/mime/mimetreeparser/interface.cpp
+++ b/framework/src/domain/mime/mimetreeparser/interface.cpp
@@ -150,6 +150,22 @@ QMimeType MailMime::mimetype() const
150 return mimeDb.mimeTypeForName(ct->mimeType()); 150 return mimeDb.mimeTypeForName(ct->mimeType());
151} 151}
152 152
153static KMime::Headers::ContentType *contentType(KMime::Content *node)
154{
155 if (node) {
156 return node->contentType(false);
157 }
158 return nullptr;
159}
160
161bool MailMime::isText() const
162{
163 if (auto ct = contentType(d->mNode)) {
164 return ct->isText();
165 }
166 return false;
167}
168
153MailMime::Ptr MailMime::parent() const 169MailMime::Ptr MailMime::parent() const
154{ 170{
155 if (!d->parent) { 171 if (!d->parent) {
diff --git a/framework/src/domain/mime/mimetreeparser/interface.h b/framework/src/domain/mime/mimetreeparser/interface.h
index 7c3ea28b..05ad32b9 100644
--- a/framework/src/domain/mime/mimetreeparser/interface.h
+++ b/framework/src/domain/mime/mimetreeparser/interface.h
@@ -91,6 +91,7 @@ public:
91 QByteArray cid() const; 91 QByteArray cid() const;
92 QByteArray charset() const; 92 QByteArray charset() const;
93 QString filename() const; 93 QString filename() const;
94 bool isText() const;
94 95
95 // Unique identifier to ecactly this KMime::Content 96 // Unique identifier to ecactly this KMime::Content
96 QByteArray link() const; 97 QByteArray link() const;