From e452707fdfbd61be1e5633b516b653b7337e7865 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 29 May 2017 16:17:04 +0200 Subject: Reduced the messagetreeparser to aproximately what we actually require While in a much more managable state it's still not pretty. However, further refactoring can now gradually happen as we need to do further work on it. Things that should happen eventually: * Simplify the logic that creates the messageparts (we don't need the whole formatter plugin complexity) * Get rid of the nodehelper (let the parts hold the necessary data) * Get rid of partmetadata (let the part handleit) --- framework/src/domain/mime/attachmentmodel.cpp | 76 ++++++++++++++++----------- 1 file changed, 46 insertions(+), 30 deletions(-) (limited to 'framework/src/domain/mime/attachmentmodel.cpp') diff --git a/framework/src/domain/mime/attachmentmodel.cpp b/framework/src/domain/mime/attachmentmodel.cpp index 99745796..68180afe 100644 --- a/framework/src/domain/mime/attachmentmodel.cpp +++ b/framework/src/domain/mime/attachmentmodel.cpp @@ -1,5 +1,6 @@ /* Copyright (c) 2016 Sandro Knauß + Copyright (c) 2017 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by @@ -17,8 +18,9 @@ 02110-1301, USA. */ -#include "messageparser.h" -#include "mimetreeparser/interface.h" +#include "attachmentmodel.h" + +#include #include #include @@ -26,47 +28,48 @@ #include #include #include +#include +#include -QString sizeHuman(const Content::Ptr &content) +QString sizeHuman(float size) { - float num = content->content().size(); QStringList list; list << "KB" << "MB" << "GB" << "TB"; QStringListIterator i(list); QString unit("Bytes"); - while(num >= 1024.0 && i.hasNext()) + while(size >= 1024.0 && i.hasNext()) { unit = i.next(); - num /= 1024.0; + size /= 1024.0; } if (unit == "Bytes") { - return QString().setNum(num) + " " + unit; + return QString().setNum(size) + " " + unit; } else { - return QString().setNum(num,'f',2)+" "+unit; + return QString().setNum(size,'f',2)+" "+unit; } } class AttachmentModelPrivate { public: - AttachmentModelPrivate(AttachmentModel *q_ptr, const std::shared_ptr &parser); + AttachmentModelPrivate(AttachmentModel *q_ptr, const std::shared_ptr &parser); AttachmentModel *q; - std::shared_ptr mParser; - QVector mAttachments; + std::shared_ptr mParser; + QVector mAttachments; }; -AttachmentModelPrivate::AttachmentModelPrivate(AttachmentModel* q_ptr, const std::shared_ptr& parser) +AttachmentModelPrivate::AttachmentModelPrivate(AttachmentModel* q_ptr, const std::shared_ptr& parser) : q(q_ptr) , mParser(parser) { mAttachments = mParser->collectAttachmentParts(); } -AttachmentModel::AttachmentModel(std::shared_ptr parser) +AttachmentModel::AttachmentModel(std::shared_ptr parser) : d(std::unique_ptr(new AttachmentModelPrivate(this, parser))) { } @@ -94,7 +97,7 @@ QModelIndex AttachmentModel::index(int row, int column, const QModelIndex &paren } if (row < d->mAttachments.size()) { - return createIndex(row, column, d->mAttachments.at(row).get()); + return createIndex(row, column, d->mAttachments.at(row).data()); } return QModelIndex(); } @@ -110,44 +113,57 @@ QVariant AttachmentModel::data(const QModelIndex &index, int role) const } if (index.internalPointer()) { - const auto entry = static_cast(index.internalPointer()); - const auto content = entry->content().at(0); + const auto part = static_cast(index.internalPointer()); + Q_ASSERT(part); + auto node = part->node(); + if (!node) { + qWarning() << "no content for attachment"; + return {}; + } + QMimeDatabase mimeDb; + const auto mimetype = mimeDb.mimeTypeForName(QString::fromLatin1(part->mimeType())); + const auto content = node->encodedContent(); switch(role) { case TypeRole: - return content->mailMime()->mimetype().name(); + return mimetype.name(); case NameRole: - return entry->mailMime()->filename(); + return part->filename(); case IconRole: - return content->mailMime()->mimetype().iconName(); + return mimetype.iconName(); case SizeRole: - return sizeHuman(content); + return sizeHuman(content.size()); case IsEncryptedRole: - return content->encryptions().size() > 0; + return part->encryptions().size() > 0; case IsSignedRole: - return content->signatures().size() > 0; + return part->signatures().size() > 0; } } return QVariant(); } -static QString saveAttachmentToDisk(const QModelIndex &index, const QString &path) +static QString saveAttachmentToDisk(const QModelIndex &index, const QString &path, bool readonly = false) { if (index.internalPointer()) { - const auto entry = static_cast(index.internalPointer()); - const auto content = entry->content().at(0); - auto filename = entry->mailMime()->filename(); - auto data = content->mailMime()->decodedContent(); - if (content->mailMime()->isText() && !data.isEmpty()) { + const auto part = static_cast(index.internalPointer()); + Q_ASSERT(part); + auto node = part->node(); + auto data = node->decodedContent(); + if (part->isText()) { // convert CRLF to LF before writing text attachments to disk data = KMime::CRLFtoLF(data); } - auto fname = path + filename; + auto fname = path + part->filename(); QFile f(fname); if (!f.open(QIODevice::ReadWrite)) { qWarning() << "Failed to write attachment to file:" << fname << " Error: " << f.errorString(); return {}; } f.write(data); + if (readonly) { + // make file read-only so that nobody gets the impression that he migh edit attached files + f.setPermissions(QFileDevice::ReadUser); + } + f.close(); qInfo() << "Wrote attachment to file: " << fname; return fname; } @@ -170,7 +186,7 @@ bool AttachmentModel::openAttachment(const QModelIndex &index) { auto downloadDir = QStandardPaths::writableLocation(QStandardPaths::TempLocation)+ "/kube/"; QDir{}.mkpath(downloadDir); - const auto filePath = ::saveAttachmentToDisk(index, downloadDir); + const auto filePath = ::saveAttachmentToDisk(index, downloadDir, true); if (!filePath.isEmpty()) { QDesktopServices::openUrl(QUrl("file://" + filePath)); return true; -- cgit v1.2.3