From 2fdddd2f795da4645dc9a48fee4865324143a21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Mon, 18 Jul 2016 15:35:07 +0200 Subject: first tests with mimetreeparser interface --- framework/domain/mimetreeparser/interface.cpp | 335 ++++++++++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 framework/domain/mimetreeparser/interface.cpp (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp new file mode 100644 index 00000000..6a399015 --- /dev/null +++ b/framework/domain/mimetreeparser/interface.cpp @@ -0,0 +1,335 @@ +/* + Copyright (c) 2016 Sandro Knauß + + 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 + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "interface.h" + +#include "stringhtmlwriter.h" +#include "objecttreesource.h" + +#include +#include +#include +#include + +#include +#include + +class PartPrivate +{ +public: + PartPrivate(Part *part); + void appendSubPart(Part::Ptr subpart); + + QVector subParts(); + + const std::weak_ptr &parent() const; +private: + Part *q; + std::weak_ptr mParent; + QVector mSubParts; +}; + +PartPrivate::PartPrivate(Part* part) + :q(part) +{ + +} + +void PartPrivate::appendSubPart(Part::Ptr subpart) +{ + subpart->d->mParent = Part::Ptr(q); + mSubParts.append(subpart); +} + +const std::weak_ptr &PartPrivate::parent() const +{ + return mParent; +} + +QVector< Part::Ptr > PartPrivate::subParts() +{ + return mSubParts; +} + +Part::Part() + : d(std::unique_ptr(new PartPrivate(this))) +{ + +} + +bool Part::hasSubParts() const +{ + return !subParts().isEmpty(); +} + +QVector Part::subParts() const +{ + return d->subParts(); +} + +QByteArray Part::type() const +{ + return "Part"; +} + +QVector Part::encryptions() const +{ + auto parent = d->parent().lock(); + if (parent) { + return parent->encryptions(); + } else { + return QVector(); + } +} + +QVector Part::signatures() const +{ + auto parent = d->parent().lock(); + if (parent) { + return parent->signatures(); + } else { + return QVector(); + } +} + +class ContentPrivate +{ +public: + QByteArray mContent; + QByteArray mCodec; + Part *mParent; + Content *q; +}; + +Content::Content(const QByteArray& content, ContentPart *parent) + : d(std::unique_ptr(new ContentPrivate)) +{ + d->q = this; + d->mContent = content; + d->mCodec = "utf-8"; + d->mParent = parent; +} + +Content::~Content() +{ +} + +QVector< Encryption > Content::encryptions() const +{ + if (d->mParent) { + return d->mParent->encryptions(); + } + return QVector(); +} + +QVector< Signature > Content::signatures() const +{ + if (d->mParent) { + return d->mParent->signatures(); + } + return QVector(); +} + +class ContentPartPrivate +{ +public: + void fillFrom(MimeTreeParser::TextMessagePart::Ptr part); + void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); + void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part); + + QVector contents() const; + + ContentPart *q; + +private: + QVector mContents; + ContentPart::Types mTypes; +}; + +void ContentPartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) +{ + mTypes = ContentPart::PlainText; + foreach (const auto &mp, part->subParts()) { + auto content = std::make_shared(mp->text().toLocal8Bit(), q); + mContents.append(content); + } +} + +void ContentPartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part) +{ + mTypes = ContentPart::Html; +} + +void ContentPartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part) +{ + mTypes = ContentPart::Html | ContentPart::PlainText; +} + +ContentPart::ContentPart() + : d(std::unique_ptr(new ContentPartPrivate)) +{ + d->q = this; +} + +ContentPart::~ContentPart() +{ + +} + +QByteArray ContentPart::type() const +{ + return "ContentPart"; +} + +class MimePartPrivate +{ +public: + void fillFrom(MimeTreeParser::MessagePart::Ptr part); +}; + +QByteArray MimePart::type() const +{ + return "MimePart"; +} + +class AttachmentPartPrivate +{ +public: + void fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part); +}; + +void AttachmentPartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part) +{ + +} + +QByteArray AttachmentPart::type() const +{ + return "AttachmentPart"; +} + +class ParserPrivate +{ +public: + ParserPrivate(Parser *parser); + + void setMessage(const QByteArray &mimeMessage); + void createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree); + + Part::Ptr mTree; +private: + Parser *q; + + MimeTreeParser::MessagePart::Ptr mPartTree; + std::shared_ptr mNodeHelper; + QString mHtml; + QMap mEmbeddedPartMap; +}; + +ParserPrivate::ParserPrivate(Parser* parser) + : q(parser) + , mNodeHelper(std::make_shared()) +{ + +} + +void ParserPrivate::setMessage(const QByteArray& mimeMessage) +{ + const auto mailData = KMime::CRLFtoLF(mimeMessage); + KMime::Message::Ptr msg(new KMime::Message); + msg->setContent(mailData); + msg->parse(); + + // render the mail + StringHtmlWriter htmlWriter; + QImage paintDevice; + ObjectTreeSource source(&htmlWriter); + MimeTreeParser::ObjectTreeParser otp(&source, mNodeHelper.get()); + + otp.parseObjectTree(msg.data()); + mPartTree = otp.parsedPart().dynamicCast(); + + mEmbeddedPartMap = htmlWriter.embeddedParts(); + mHtml = htmlWriter.html(); + + mTree = std::make_shared(); + createTree(mPartTree, mTree); +} + + +void ParserPrivate::createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree) +{ + + foreach (const auto &mp, start->subParts()) { + const auto m = mp.dynamicCast(); + const auto text = mp.dynamicCast(); + const auto alternative = mp.dynamicCast(); + const auto html = mp.dynamicCast(); + const auto attachment = mp.dynamicCast(); + if (text) { + auto part = std::make_shared(); + part->d->fillFrom(text); + mTree->d->appendSubPart(part); + } else if (alternative) { + auto part = std::make_shared(); + part->d->fillFrom(alternative); + mTree->d->appendSubPart(part); + } else if (html) { + auto part = std::make_shared(); + part->d->fillFrom(html); + mTree->d->appendSubPart(part); + } else if (attachment) { + auto part = std::make_shared(); + part->d->fillFrom(attachment); + mTree->d->appendSubPart(part); + } else { + createTree(m, tree); + } + } +} + +Parser::Parser(const QByteArray& mimeMessage) + :d(std::unique_ptr(new ParserPrivate(this))) +{ + d->setMessage(mimeMessage); +} + +Parser::~Parser() +{ +} + +ContentPart::Ptr Parser::collectContentPart(const Part::Ptr &start) const +{ + foreach (const auto &part, start->subParts()) { + if (part->type() == "ContentPart") { + return std::dynamic_pointer_cast(part); + } else { + auto ret = collectContentPart(part); + if (ret) { + return ret; + } + } + } + return ContentPart::Ptr(); +} + +ContentPart::Ptr Parser::collectContentPart() const +{ + return collectContentPart(d->mTree); +} -- cgit v1.2.3 From 9516f3b02f74f239ce2776abf7cf1147952065cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Tue, 19 Jul 2016 14:46:23 +0200 Subject: new mimetreeparser interface Reviewers: cmollekopf Maniphest Tasks: T3208 Differential Revision: https://phabricator.kde.org/D2221 --- framework/domain/mimetreeparser/interface.cpp | 89 ++++++++++++++++++++------- 1 file changed, 66 insertions(+), 23 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index 6a399015..c239fcc0 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -38,26 +38,27 @@ public: QVector subParts(); - const std::weak_ptr &parent() const; + Part *parent() const; private: Part *q; - std::weak_ptr mParent; + Part *mParent; QVector mSubParts; }; PartPrivate::PartPrivate(Part* part) - :q(part) + : q(part) + , mParent(Q_NULLPTR) { } void PartPrivate::appendSubPart(Part::Ptr subpart) { - subpart->d->mParent = Part::Ptr(q); + subpart->d->mParent = q; mSubParts.append(subpart); } -const std::weak_ptr &PartPrivate::parent() const +Part *PartPrivate::parent() const { return mParent; } @@ -90,7 +91,7 @@ QByteArray Part::type() const QVector Part::encryptions() const { - auto parent = d->parent().lock(); + auto parent = d->parent(); if (parent) { return parent->encryptions(); } else { @@ -100,7 +101,7 @@ QVector Part::encryptions() const QVector Part::signatures() const { - auto parent = d->parent().lock(); + auto parent = d->parent(); if (parent) { return parent->signatures(); } else { @@ -146,6 +147,16 @@ QVector< Signature > Content::signatures() const return QVector(); } +QByteArray Content::content() const +{ + return d->mContent; +} + +QByteArray Content::charset() const +{ + return d->mCodec; +} + class ContentPartPrivate { public: @@ -153,12 +164,14 @@ public: void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part); - QVector contents() const; + QVector content() const; ContentPart *q; + + ContentPart::Types types() const; private: - QVector mContents; + QVector mContent; ContentPart::Types mTypes; }; @@ -167,7 +180,7 @@ void ContentPartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) mTypes = ContentPart::PlainText; foreach (const auto &mp, part->subParts()) { auto content = std::make_shared(mp->text().toLocal8Bit(), q); - mContents.append(content); + mContent.append(content); } } @@ -181,6 +194,22 @@ void ContentPartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr pa mTypes = ContentPart::Html | ContentPart::PlainText; } +ContentPart::Types ContentPartPrivate::types() const +{ + return mTypes; +} + +QVector ContentPartPrivate::content() const +{ + return mContent; +} + +QVector ContentPart::content(ContentPart::Type ct) const +{ + return d->content(); +} + + ContentPart::ContentPart() : d(std::unique_ptr(new ContentPartPrivate)) { @@ -197,6 +226,11 @@ QByteArray ContentPart::type() const return "ContentPart"; } +ContentPart::Types ContentPart::availableContents() const +{ + return d->types(); +} + class MimePartPrivate { public: @@ -230,7 +264,7 @@ public: ParserPrivate(Parser *parser); void setMessage(const QByteArray &mimeMessage); - void createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree); + void createTree(const MimeTreeParser::MessagePart::Ptr& start, const Part::Ptr& tree); Part::Ptr mTree; private: @@ -273,9 +307,8 @@ void ParserPrivate::setMessage(const QByteArray& mimeMessage) } -void ParserPrivate::createTree(MimeTreeParser::MessagePart::Ptr start, Part::Ptr tree) +void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, const Part::Ptr &tree) { - foreach (const auto &mp, start->subParts()) { const auto m = mp.dynamicCast(); const auto text = mp.dynamicCast(); @@ -316,16 +349,10 @@ Parser::~Parser() ContentPart::Ptr Parser::collectContentPart(const Part::Ptr &start) const { - foreach (const auto &part, start->subParts()) { - if (part->type() == "ContentPart") { - return std::dynamic_pointer_cast(part); - } else { - auto ret = collectContentPart(part); - if (ret) { - return ret; - } - } - } + const auto ret = collect(start, [](const Part::Ptr &p){return p->type() == "ContentPart";}, [](const ContentPart::Ptr &p){return true;}); + if (ret.size() > 0) { + return ret[0]; + }; return ContentPart::Ptr(); } @@ -333,3 +360,19 @@ ContentPart::Ptr Parser::collectContentPart() const { return collectContentPart(d->mTree); } + +template +QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const +{ + QVector ret; + foreach (const auto &part, start->subParts()) { + if (select(part)){ + const auto p = std::dynamic_pointer_cast(part); + if (p && filter(p)) { + ret.append(p); + } + ret += collect(part, select, filter); + } + } + return ret; +} -- cgit v1.2.3 From 550aa371cbf39d7d0cb735f890b338a3ac6883ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Wed, 20 Jul 2016 10:04:49 +0200 Subject: add encrypted tests --- framework/domain/mimetreeparser/interface.cpp | 55 +++++++++++---------------- 1 file changed, 22 insertions(+), 33 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index c239fcc0..e34ffda7 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -18,6 +18,7 @@ */ #include "interface.h" +#include "interface_p.h" #include "stringhtmlwriter.h" #include "objecttreesource.h" @@ -28,7 +29,6 @@ #include #include -#include class PartPrivate { @@ -164,34 +164,42 @@ public: void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part); - QVector content() const; + QVector content(ContentPart::Type ct) const; ContentPart *q; ContentPart::Types types() const; - + private: - QVector mContent; + QMap> mContent; ContentPart::Types mTypes; }; void ContentPartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) { + qDebug() << "jepp"; mTypes = ContentPart::PlainText; foreach (const auto &mp, part->subParts()) { auto content = std::make_shared(mp->text().toLocal8Bit(), q); - mContent.append(content); + mContent[ContentPart::PlainText].append(content); } } void ContentPartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part) { mTypes = ContentPart::Html; + auto content = std::make_shared(part->text().toLocal8Bit(), q); + mContent[ContentPart::Html].append(content); } void ContentPartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part) { mTypes = ContentPart::Html | ContentPart::PlainText; + + auto content = std::make_shared(part->htmlContent().toLocal8Bit(), q); + mContent[ContentPart::Html].append(content); + content = std::make_shared(part->plaintextContent().toLocal8Bit(), q); + mContent[ContentPart::PlainText].append(content); } ContentPart::Types ContentPartPrivate::types() const @@ -199,14 +207,14 @@ ContentPart::Types ContentPartPrivate::types() const return mTypes; } -QVector ContentPartPrivate::content() const +QVector ContentPartPrivate::content(ContentPart::Type ct) const { - return mContent; + return mContent[ct]; } QVector ContentPart::content(ContentPart::Type ct) const { - return d->content(); + return d->content(ct); } @@ -258,24 +266,6 @@ QByteArray AttachmentPart::type() const return "AttachmentPart"; } -class ParserPrivate -{ -public: - ParserPrivate(Parser *parser); - - void setMessage(const QByteArray &mimeMessage); - void createTree(const MimeTreeParser::MessagePart::Ptr& start, const Part::Ptr& tree); - - Part::Ptr mTree; -private: - Parser *q; - - MimeTreeParser::MessagePart::Ptr mPartTree; - std::shared_ptr mNodeHelper; - QString mHtml; - QMap mEmbeddedPartMap; -}; - ParserPrivate::ParserPrivate(Parser* parser) : q(parser) , mNodeHelper(std::make_shared()) @@ -292,7 +282,6 @@ void ParserPrivate::setMessage(const QByteArray& mimeMessage) // render the mail StringHtmlWriter htmlWriter; - QImage paintDevice; ObjectTreeSource source(&htmlWriter); MimeTreeParser::ObjectTreeParser otp(&source, mNodeHelper.get()); @@ -315,7 +304,11 @@ void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, co const auto alternative = mp.dynamicCast(); const auto html = mp.dynamicCast(); const auto attachment = mp.dynamicCast(); - if (text) { + if (attachment) { + auto part = std::make_shared(); + part->d->fillFrom(attachment); + mTree->d->appendSubPart(part); + } else if (text) { auto part = std::make_shared(); part->d->fillFrom(text); mTree->d->appendSubPart(part); @@ -327,10 +320,6 @@ void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, co auto part = std::make_shared(); part->d->fillFrom(html); mTree->d->appendSubPart(part); - } else if (attachment) { - auto part = std::make_shared(); - part->d->fillFrom(attachment); - mTree->d->appendSubPart(part); } else { createTree(m, tree); } @@ -349,7 +338,7 @@ Parser::~Parser() ContentPart::Ptr Parser::collectContentPart(const Part::Ptr &start) const { - const auto ret = collect(start, [](const Part::Ptr &p){return p->type() == "ContentPart";}, [](const ContentPart::Ptr &p){return true;}); + const auto ret = collect(start, [](const Part::Ptr &p){return p->type() == "ContentPart";}, [](const ContentPart::Ptr &p){return true;}); if (ret.size() > 0) { return ret[0]; }; -- cgit v1.2.3 From cf5b3e797421e7dbf2c0d7b1efff91fc07277652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Wed, 20 Jul 2016 17:35:29 +0200 Subject: new thoughts for interface --- framework/domain/mimetreeparser/interface.cpp | 165 +++++++++++++++----------- 1 file changed, 97 insertions(+), 68 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index e34ffda7..aa7e3911 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -89,6 +89,16 @@ QByteArray Part::type() const return "Part"; } +QVector Part::availableContents() const +{ + return QVector(); +} + +QVector Part::content() const +{ + return QVector(); +} + QVector Part::encryptions() const { auto parent = d->parent(); @@ -118,7 +128,7 @@ public: Content *q; }; -Content::Content(const QByteArray& content, ContentPart *parent) +Content::Content(const QByteArray& content, Part *parent) : d(std::unique_ptr(new ContentPrivate)) { d->q = this; @@ -157,113 +167,141 @@ QByteArray Content::charset() const return d->mCodec; } -class ContentPartPrivate +class AlternativePartPrivate { public: - void fillFrom(MimeTreeParser::TextMessagePart::Ptr part); - void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); void fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part); - QVector content(ContentPart::Type ct) const; + QVector content(const QByteArray &ct) const; - ContentPart *q; + AlternativePart *q; - ContentPart::Types types() const; + QVector types() const; private: - QMap> mContent; - ContentPart::Types mTypes; + QMap> mContent; + QVector mTypes; }; -void ContentPartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) +void AlternativePartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part) { - qDebug() << "jepp"; - mTypes = ContentPart::PlainText; - foreach (const auto &mp, part->subParts()) { - auto content = std::make_shared(mp->text().toLocal8Bit(), q); - mContent[ContentPart::PlainText].append(content); - } + mTypes = QVector() << "html" << "plaintext"; + + auto content = std::make_shared(part->htmlContent().toLocal8Bit(), q); + mContent["html"].append(content); + content = std::make_shared(part->plaintextContent().toLocal8Bit(), q); + mContent["plaintext"].append(content); } -void ContentPartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part) +QVector AlternativePartPrivate::types() const { - mTypes = ContentPart::Html; - auto content = std::make_shared(part->text().toLocal8Bit(), q); - mContent[ContentPart::Html].append(content); + return mTypes; } -void ContentPartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Ptr part) +QVector AlternativePartPrivate::content(const QByteArray& ct) const { - mTypes = ContentPart::Html | ContentPart::PlainText; + return mContent[ct]; +} - auto content = std::make_shared(part->htmlContent().toLocal8Bit(), q); - mContent[ContentPart::Html].append(content); - content = std::make_shared(part->plaintextContent().toLocal8Bit(), q); - mContent[ContentPart::PlainText].append(content); +AlternativePart::AlternativePart() + : d(std::unique_ptr(new AlternativePartPrivate)) +{ + d->q = this; } -ContentPart::Types ContentPartPrivate::types() const +AlternativePart::~AlternativePart() { - return mTypes; + } -QVector ContentPartPrivate::content(ContentPart::Type ct) const +QByteArray AlternativePart::type() const { - return mContent[ct]; + return "AlternativePart"; } -QVector ContentPart::content(ContentPart::Type ct) const +QVector AlternativePart::availableContents() const { - return d->content(ct); + return d->types(); } +QVector AlternativePart::content() const +{ + return d->content(availableContents().first()); +} -ContentPart::ContentPart() - : d(std::unique_ptr(new ContentPartPrivate)) +QVector AlternativePart::content(const QByteArray& ct) const { - d->q = this; + return d->content(ct); } -ContentPart::~ContentPart() +class SinglePartPrivate { +public: + void fillFrom(MimeTreeParser::TextMessagePart::Ptr part); + void fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part); + void fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part); + SinglePart *q; + + QVector mContent; + QByteArray mType; +}; +void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) +{ + mType = "plaintext"; + mContent.clear(); + foreach (const auto &mp, part->subParts()) { + mContent.append(std::make_shared(mp->text().toLocal8Bit(), q)); + } } -QByteArray ContentPart::type() const +void SinglePartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part) { - return "ContentPart"; + mType = "html"; + mContent.clear(); + mContent.append(std::make_shared(part->text().toLocal8Bit(), q)); } -ContentPart::Types ContentPart::availableContents() const +void SinglePartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part) { - return d->types(); + } -class MimePartPrivate +SinglePart::SinglePart() + : d(std::unique_ptr(new SinglePartPrivate)) { -public: - void fillFrom(MimeTreeParser::MessagePart::Ptr part); -}; + d->q = this; +} -QByteArray MimePart::type() const +SinglePart::~SinglePart() { - return "MimePart"; + } -class AttachmentPartPrivate +QVector SinglePart::availableContents() const { -public: - void fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part); -}; + return QVector() << d->mType; +} -void AttachmentPartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part) +QVector< Content::Ptr > SinglePart::content() const { + return d->mContent; +} +QByteArray SinglePart::type() const +{ + return "SinglePart"; } -QByteArray AttachmentPart::type() const +class MimePartPrivate +{ +public: + void fillFrom(MimeTreeParser::MessagePart::Ptr part); +}; + +QByteArray MimePart::type() const { - return "AttachmentPart"; + return "MimePart"; } ParserPrivate::ParserPrivate(Parser* parser) @@ -309,15 +347,15 @@ void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, co part->d->fillFrom(attachment); mTree->d->appendSubPart(part); } else if (text) { - auto part = std::make_shared(); + auto part = std::make_shared(); part->d->fillFrom(text); mTree->d->appendSubPart(part); } else if (alternative) { - auto part = std::make_shared(); + auto part = std::make_shared(); part->d->fillFrom(alternative); mTree->d->appendSubPart(part); } else if (html) { - auto part = std::make_shared(); + auto part = std::make_shared(); part->d->fillFrom(html); mTree->d->appendSubPart(part); } else { @@ -336,18 +374,9 @@ Parser::~Parser() { } -ContentPart::Ptr Parser::collectContentPart(const Part::Ptr &start) const +QVector Parser::collectContentParts() const { - const auto ret = collect(start, [](const Part::Ptr &p){return p->type() == "ContentPart";}, [](const ContentPart::Ptr &p){return true;}); - if (ret.size() > 0) { - return ret[0]; - }; - return ContentPart::Ptr(); -} - -ContentPart::Ptr Parser::collectContentPart() const -{ - return collectContentPart(d->mTree); + return collect(d->mTree, [](const Part::Ptr &p){return p->availableContents().indexOf("html") > -1 || p->availableContents().indexOf("text") > -1;}, [](const Part::Ptr &p){return true;}); } template @@ -364,4 +393,4 @@ QVector Parser::collect(const Part::Ptr &start, std::function Date: Fri, 22 Jul 2016 13:23:17 +0200 Subject: fixes the build issues --- framework/domain/mimetreeparser/interface.cpp | 103 +++++++++++++++++--------- 1 file changed, 69 insertions(+), 34 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index aa7e3911..5cf36d10 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -141,7 +141,7 @@ Content::~Content() { } -QVector< Encryption > Content::encryptions() const +QVector Content::encryptions() const { if (d->mParent) { return d->mParent->encryptions(); @@ -149,7 +149,7 @@ QVector< Encryption > Content::encryptions() const return QVector(); } -QVector< Signature > Content::signatures() const +QVector Content::signatures() const { if (d->mParent) { return d->mParent->signatures(); @@ -167,6 +167,19 @@ QByteArray Content::charset() const return d->mCodec; } +HtmlContent::HtmlContent(const QByteArray& content, Part* parent) + : Content(content, parent) +{ + +} + +PlainTextContent::PlainTextContent(const QByteArray& content, Part* parent) + : Content(content, parent) +{ + +} + + class AlternativePartPrivate { public: @@ -187,7 +200,7 @@ void AlternativePartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Pt { mTypes = QVector() << "html" << "plaintext"; - auto content = std::make_shared(part->htmlContent().toLocal8Bit(), q); + Content::Ptr content = std::make_shared(part->htmlContent().toLocal8Bit(), q); mContent["html"].append(content); content = std::make_shared(part->plaintextContent().toLocal8Bit(), q); mContent["plaintext"].append(content); @@ -224,11 +237,6 @@ QVector AlternativePart::availableContents() const return d->types(); } -QVector AlternativePart::content() const -{ - return d->content(availableContents().first()); -} - QVector AlternativePart::content(const QByteArray& ct) const { return d->content(ct); @@ -283,9 +291,12 @@ QVector SinglePart::availableContents() const return QVector() << d->mType; } -QVector< Content::Ptr > SinglePart::content() const +QVector< Content::Ptr > SinglePart::content(const QByteArray &ct) const { - return d->mContent; + if (ct == d->mType) { + return d->mContent; + } + return QVector(); } QByteArray SinglePart::type() const @@ -293,17 +304,6 @@ QByteArray SinglePart::type() const return "SinglePart"; } -class MimePartPrivate -{ -public: - void fillFrom(MimeTreeParser::MessagePart::Ptr part); -}; - -QByteArray MimePart::type() const -{ - return "MimePart"; -} - ParserPrivate::ParserPrivate(Parser* parser) : q(parser) , mNodeHelper(std::make_shared()) @@ -343,7 +343,7 @@ void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, co const auto html = mp.dynamicCast(); const auto attachment = mp.dynamicCast(); if (attachment) { - auto part = std::make_shared(); + auto part = std::make_shared(); part->d->fillFrom(attachment); mTree->d->appendSubPart(part); } else if (text) { @@ -376,20 +376,55 @@ Parser::~Parser() QVector Parser::collectContentParts() const { - return collect(d->mTree, [](const Part::Ptr &p){return p->availableContents().indexOf("html") > -1 || p->availableContents().indexOf("text") > -1;}, [](const Part::Ptr &p){return true;}); -} - -template -QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const -{ - QVector ret; + return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, + [](const Content::Ptr &content){ + const auto mime = content->mailMime(); + + if (!mime) { + return true; + } + + if (mime->isFirstTextPart()) { + return true; + } + const auto cd = mime->disposition(); + if (cd && cd == MailMime::Inline) { + // explict "inline" disposition: + return true; + } + if (cd && cd == MailMime::Attachment) { + // explicit "attachment" disposition: + return false; + } + + const auto ct = mime->mimetype(); + if (ct.name().trimmed().toLower() == "text" && ct.name().trimmed().isEmpty() && + (!mime || mime->filename().trimmed().isEmpty())) { + // text/* w/o filename parameter: + return true; + } + return false; + }); +} + +QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const +{ + QVector ret; foreach (const auto &part, start->subParts()) { - if (select(part)){ - const auto p = std::dynamic_pointer_cast(part); - if (p && filter(p)) { - ret.append(p); + QVector contents; + foreach(const auto &ct, part->availableContents()) { + foreach(const auto &content, part->content(ct)) { + if (filter(content)) { + contents.append(ct); + break; + } } - ret += collect(part, select, filter); + } + if (!contents.isEmpty()) { + ret.append(part); + } + if (select(part)){ + ret += collect(part, select, filter); } } return ret; -- cgit v1.2.3 From 0272f1e8bb7f8c86c86958e3e022aac8b34a266c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Tue, 26 Jul 2016 13:52:06 +0200 Subject: make the tests compile again --- framework/domain/mimetreeparser/interface.cpp | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index 5cf36d10..a76a6cde 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -28,8 +28,77 @@ #include #include +#include +#include #include +class MailMimePrivate +{ +public: + KMime::Content *mNode; + MailMime *q; +}; + +MailMime::MailMime() + : d(std::unique_ptr(new MailMimePrivate())) +{ + d->q = this; +} + +bool MailMime::isFirstTextPart() const +{ + if (!d->mNode) { + return false; + } + return (d->mNode->topLevel()->textContent() == d->mNode); +} + +MailMime::Disposition MailMime::disposition() const +{ + if (!d->mNode) { + return Invalid; + } + const auto cd = d->mNode->contentDisposition(false); + if (!cd) { + return Invalid; + } + switch (cd->disposition()){ + case KMime::Headers::CDinline: + return Inline; + case KMime::Headers::CDattachment: + return Attachment; + default: + return Invalid; + } +} + +QString MailMime::filename() const +{ + if (!d->mNode) { + return QString(); + } + const auto cd = d->mNode->contentDisposition(false); + if (!cd) { + return QString(); + } + return cd->filename(); +} + +QMimeType MailMime::mimetype() const +{ + if (!d->mNode) { + return QMimeType(); + } + + const auto ct = d->mNode->contentType(false); + if (!ct) { + return QMimeType(); + } + + QMimeDatabase mimeDb; + return mimeDb.mimeTypeForName(ct->mimeType()); +} + class PartPrivate { public: @@ -39,10 +108,13 @@ public: QVector subParts(); Part *parent() const; + + const MailMime::Ptr &mailMime() const; private: Part *q; Part *mParent; QVector mSubParts; + MailMime::Ptr mMailMime; }; PartPrivate::PartPrivate(Part* part) @@ -68,6 +140,11 @@ QVector< Part::Ptr > PartPrivate::subParts() return mSubParts; } +const MailMime::Ptr& PartPrivate::mailMime() const +{ + return mMailMime; +} + Part::Part() : d(std::unique_ptr(new PartPrivate(this))) { @@ -95,6 +172,11 @@ QVector Part::availableContents() const } QVector Part::content() const +{ + return content(availableContents().first()); +} + +QVector Part::content(const QByteArray& ct) const { return QVector(); } @@ -119,6 +201,11 @@ QVector Part::signatures() const } } +MailMime::Ptr Part::mailMime() const +{ + return d->mailMime(); +} + class ContentPrivate { public: @@ -126,6 +213,7 @@ public: QByteArray mCodec; Part *mParent; Content *q; + MailMime::Ptr mMailMime; }; Content::Content(const QByteArray& content, Part *parent) @@ -167,18 +255,37 @@ QByteArray Content::charset() const return d->mCodec; } +QByteArray Content::type() const +{ + return "Content"; +} + +MailMime::Ptr Content::mailMime() const +{ + return d->mMailMime; +} + HtmlContent::HtmlContent(const QByteArray& content, Part* parent) : Content(content, parent) { } +QByteArray HtmlContent::type() const +{ + return "HtmlContent"; +} + PlainTextContent::PlainTextContent(const QByteArray& content, Part* parent) : Content(content, parent) { } +QByteArray PlainTextContent::type() const +{ + return "PlainTextContent"; +} class AlternativePartPrivate { -- cgit v1.2.3 From a34e14a57c7726a99e63d767935379cba1ff6ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Tue, 2 Aug 2016 09:32:12 +0200 Subject: Implement the interface --- framework/domain/mimetreeparser/interface.cpp | 83 ++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 7 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index a76a6cde..4f45b883 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -47,12 +47,20 @@ MailMime::MailMime() bool MailMime::isFirstTextPart() const { - if (!d->mNode) { + if (!d->mNode || !d->mNode->topLevel()) { return false; } return (d->mNode->topLevel()->textContent() == d->mNode); } +bool MailMime::isTopLevelPart() const +{ + if (!d->mNode) { + return false; + } + return (d->mNode->topLevel() == d->mNode); +} + MailMime::Disposition MailMime::disposition() const { if (!d->mNode) { @@ -110,6 +118,10 @@ public: Part *parent() const; const MailMime::Ptr &mailMime() const; + void createMailMime(const MimeTreeParser::MimeMessagePart::Ptr &part); + void createMailMime(const MimeTreeParser::TextMessagePart::Ptr &part); + void createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr &part); + void createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr &part); private: Part *q; Part *mParent; @@ -124,6 +136,30 @@ PartPrivate::PartPrivate(Part* part) } +void PartPrivate::createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr& part) +{ + mMailMime = MailMime::Ptr(new MailMime); + mMailMime->d->mNode = part->mNode; +} + +void PartPrivate::createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr& part) +{ + mMailMime = MailMime::Ptr(new MailMime); + mMailMime->d->mNode = part->mNode; +} + +void PartPrivate::createMailMime(const MimeTreeParser::TextMessagePart::Ptr& part) +{ + mMailMime = MailMime::Ptr(new MailMime); + mMailMime->d->mNode = part->mNode; +} + +void PartPrivate::createMailMime(const MimeTreeParser::MimeMessagePart::Ptr& part) +{ + mMailMime = MailMime::Ptr(new MailMime); + mMailMime->d->mNode = part->mNode; +} + void PartPrivate::appendSubPart(Part::Ptr subpart) { subpart->d->mParent = q; @@ -262,7 +298,16 @@ QByteArray Content::type() const MailMime::Ptr Content::mailMime() const { - return d->mMailMime; + if (d->mMailMime) { + return d->mMailMime; + } else { + return d->mParent->mailMime(); + } +} + +Part *Content::parent() const +{ + return d->mParent; } HtmlContent::HtmlContent(const QByteArray& content, Part* parent) @@ -311,6 +356,7 @@ void AlternativePartPrivate::fillFrom(MimeTreeParser::AlternativeMessagePart::Pt mContent["html"].append(content); content = std::make_shared(part->plaintextContent().toLocal8Bit(), q); mContent["plaintext"].append(content); + q->reachParentD()->createMailMime(part); } QVector AlternativePartPrivate::types() const @@ -349,6 +395,11 @@ QVector AlternativePart::content(const QByteArray& ct) const return d->content(ct); } +PartPrivate* AlternativePart::reachParentD() const +{ + return Part::d.get(); +} + class SinglePartPrivate { public: @@ -367,6 +418,7 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) mContent.clear(); foreach (const auto &mp, part->subParts()) { mContent.append(std::make_shared(mp->text().toLocal8Bit(), q)); + q->reachParentD()->createMailMime(part); } } @@ -375,11 +427,12 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part) mType = "html"; mContent.clear(); mContent.append(std::make_shared(part->text().toLocal8Bit(), q)); + q->reachParentD()->createMailMime(part); } void SinglePartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part) { - + q->reachParentD()->createMailMime(part.staticCast()); } SinglePart::SinglePart() @@ -411,6 +464,11 @@ QByteArray SinglePart::type() const return "SinglePart"; } +PartPrivate* SinglePart::reachParentD() const +{ + return Part::d.get(); +} + ParserPrivate::ParserPrivate(Parser* parser) : q(parser) , mNodeHelper(std::make_shared()) @@ -421,16 +479,16 @@ ParserPrivate::ParserPrivate(Parser* parser) void ParserPrivate::setMessage(const QByteArray& mimeMessage) { const auto mailData = KMime::CRLFtoLF(mimeMessage); - KMime::Message::Ptr msg(new KMime::Message); - msg->setContent(mailData); - msg->parse(); + mMsg = KMime::Message::Ptr(new KMime::Message); + mMsg->setContent(mailData); + mMsg->parse(); // render the mail StringHtmlWriter htmlWriter; ObjectTreeSource source(&htmlWriter); MimeTreeParser::ObjectTreeParser otp(&source, mNodeHelper.get()); - otp.parseObjectTree(msg.data()); + otp.parseObjectTree(mMsg.data()); mPartTree = otp.parsedPart().dynamicCast(); mEmbeddedPartMap = htmlWriter.embeddedParts(); @@ -494,6 +552,16 @@ QVector Parser::collectContentParts() const if (mime->isFirstTextPart()) { return true; } + + { + const auto parent = content->parent(); + if (parent) { + const auto _mime = parent->mailMime(); + if (_mime && (_mime->isTopLevelPart() || _mime->isFirstTextPart())) { + return true; + } + } + } const auto cd = mime->disposition(); if (cd && cd == MailMime::Inline) { // explict "inline" disposition: @@ -526,6 +594,7 @@ QVector Parser::collect(const Part::Ptr &start, std::function Date: Tue, 2 Aug 2016 10:11:23 +0200 Subject: Implement collectAttachmentParts --- framework/domain/mimetreeparser/interface.cpp | 47 ++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index 4f45b883..04f0fdf2 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -433,6 +433,9 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::HtmlMessagePart::Ptr part) void SinglePartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part) { q->reachParentD()->createMailMime(part.staticCast()); + mType = q->mailMime()->mimetype().name().toUtf8(); + mContent.clear(); + mContent.append(std::make_shared(part->text().toLocal8Bit(), q)); } SinglePart::SinglePart() @@ -582,6 +585,49 @@ QVector Parser::collectContentParts() const }); } + +QVector Parser::collectAttachmentParts() const +{ + return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, + [](const Content::Ptr &content){ + const auto mime = content->mailMime(); + + if (!mime) { + return false; + } + + if (mime->isFirstTextPart()) { + return false; + } + + { + const auto parent = content->parent(); + if (parent) { + const auto _mime = parent->mailMime(); + if (_mime && (_mime->isTopLevelPart() || _mime->isFirstTextPart())) { + return false; + } + } + } + const auto cd = mime->disposition(); + if (cd && cd == MailMime::Inline) { + // explict "inline" disposition: + return false; + } + if (cd && cd == MailMime::Attachment) { + // explicit "attachment" disposition: + return true; + } + + const auto ct = mime->mimetype(); + if (ct.name().trimmed().toLower() == "text" && ct.name().trimmed().isEmpty() && + (!mime || mime->filename().trimmed().isEmpty())) { + // text/* w/o filename parameter: + return false; + } + return true; + }); +} QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const { QVector ret; @@ -594,7 +640,6 @@ QVector Parser::collect(const Part::Ptr &start, std::function Date: Tue, 2 Aug 2016 18:14:00 +0200 Subject: make signs & encrytiopn work --- framework/domain/mimetreeparser/interface.cpp | 204 +++++++++++++++++++++++--- 1 file changed, 184 insertions(+), 20 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index 04f0fdf2..d6354c9e 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -122,10 +122,21 @@ public: void createMailMime(const MimeTreeParser::TextMessagePart::Ptr &part); void createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr &part); void createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr &part); + + void appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr &part); + void appendSignature(const MimeTreeParser::SignedMessagePart::Ptr &part); + + void setSignatures(const QVector &sigs); + void setEncryptions(const QVector &encs); + + const QVector &encryptions() const; + const QVector &signatures() const; private: Part *q; Part *mParent; QVector mSubParts; + QVector mEncryptions; + QVector mSignatures; MailMime::Ptr mMailMime; }; @@ -166,6 +177,27 @@ void PartPrivate::appendSubPart(Part::Ptr subpart) mSubParts.append(subpart); } +void PartPrivate::appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part) +{ + mEncryptions.append(Encryption::Ptr(new Encryption)); +} + +void PartPrivate::setEncryptions(const QVector< Encryption::Ptr >& encs) +{ + mEncryptions = encs; +} + +void PartPrivate::appendSignature(const MimeTreeParser::SignedMessagePart::Ptr& part) +{ + mSignatures.append(Signature::Ptr(new Signature)); +} + + +void PartPrivate::setSignatures(const QVector< Signature::Ptr >& sigs) +{ + mSignatures = sigs; +} + Part *PartPrivate::parent() const { return mParent; @@ -181,6 +213,16 @@ const MailMime::Ptr& PartPrivate::mailMime() const return mMailMime; } +const QVector< Encryption::Ptr >& PartPrivate::encryptions() const +{ + return mEncryptions; +} + +const QVector< Signature::Ptr >& PartPrivate::signatures() const +{ + return mSignatures; +} + Part::Part() : d(std::unique_ptr(new PartPrivate(this))) { @@ -217,24 +259,24 @@ QVector Part::content(const QByteArray& ct) const return QVector(); } -QVector Part::encryptions() const +QVector Part::encryptions() const { + auto ret = d->encryptions(); auto parent = d->parent(); if (parent) { - return parent->encryptions(); - } else { - return QVector(); + ret.append(parent->encryptions()); } + return ret; } -QVector Part::signatures() const +QVector Part::signatures() const { + auto ret = d->signatures(); auto parent = d->parent(); if (parent) { - return parent->signatures(); - } else { - return QVector(); + ret.append(parent->signatures()); } + return ret; } MailMime::Ptr Part::mailMime() const @@ -250,8 +292,23 @@ public: Part *mParent; Content *q; MailMime::Ptr mMailMime; + QVector mEncryptions; + QVector mSignatures; + void appendSignature(const MimeTreeParser::SignedMessagePart::Ptr &sig); + void appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr &enc); }; +void ContentPrivate::appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& enc) +{ + mEncryptions.append(Encryption::Ptr(new Encryption)); +} + +void ContentPrivate::appendSignature(const MimeTreeParser::SignedMessagePart::Ptr& sig) +{ + mSignatures.append(Signature::Ptr(new Signature)); +} + + Content::Content(const QByteArray& content, Part *parent) : d(std::unique_ptr(new ContentPrivate)) { @@ -261,24 +318,32 @@ Content::Content(const QByteArray& content, Part *parent) d->mParent = parent; } +Content::Content(ContentPrivate* d_ptr) + : d(std::unique_ptr(d_ptr)) +{ + d->q = this; +} + Content::~Content() { } -QVector Content::encryptions() const +QVector Content::encryptions() const { + auto ret = d->mEncryptions; if (d->mParent) { - return d->mParent->encryptions(); + ret.append(d->mParent->encryptions()); } - return QVector(); + return ret; } -QVector Content::signatures() const +QVector Content::signatures() const { + auto ret = d->mSignatures; if (d->mParent) { - return d->mParent->signatures(); + ret.append(d->mParent->signatures()); } - return QVector(); + return ret; } QByteArray Content::content() const @@ -327,6 +392,19 @@ PlainTextContent::PlainTextContent(const QByteArray& content, Part* parent) } +PlainTextContent::PlainTextContent(ContentPrivate* d_ptr) + : Content(d_ptr) +{ + +} + +HtmlContent::HtmlContent(ContentPrivate* d_ptr) + : Content(d_ptr) +{ + +} + + QByteArray PlainTextContent::type() const { return "PlainTextContent"; @@ -417,7 +495,23 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) mType = "plaintext"; mContent.clear(); foreach (const auto &mp, part->subParts()) { - mContent.append(std::make_shared(mp->text().toLocal8Bit(), q)); + auto d_ptr = new ContentPrivate; + d_ptr->mContent = part->text().toLocal8Bit(); + d_ptr->mParent = q; + d_ptr->mCodec = "utf-8"; + const auto enc = mp.dynamicCast(); + auto sig = mp.dynamicCast(); + if (enc) { + d_ptr->appendEncryption(enc); + const auto s = enc->subParts(); + if (s.size() == 1) { + sig = s[0].dynamicCast(); + } + } + if (sig) { + d_ptr->appendSignature(sig); + } + mContent.append(std::make_shared(d_ptr)); q->reachParentD()->createMailMime(part); } } @@ -472,6 +566,54 @@ PartPrivate* SinglePart::reachParentD() const return Part::d.get(); } +class SignaturePrivate +{ +public: + Signature *q; +}; + +Signature::Signature() + :d(std::unique_ptr(new SignaturePrivate)) +{ + d->q = this; +} + + +Signature::Signature(SignaturePrivate *d_ptr) + :d(std::unique_ptr(d_ptr)) +{ + d->q = this; +} + +Signature::~Signature() +{ + +} + + +class EncryptionPrivate +{ +public: + Encryption *q; +}; + +Encryption::Encryption(EncryptionPrivate *d_ptr) + :d(std::unique_ptr(d_ptr)) +{ + d->q = this; +} + +Encryption::Encryption() + :d(std::unique_ptr(new EncryptionPrivate)) +{ + d->q = this; +} + +Encryption::~Encryption() +{ + +} + ParserPrivate::ParserPrivate(Parser* parser) : q(parser) , mNodeHelper(std::make_shared()) @@ -513,21 +655,43 @@ void ParserPrivate::createTree(const MimeTreeParser::MessagePart::Ptr &start, co if (attachment) { auto part = std::make_shared(); part->d->fillFrom(attachment); - mTree->d->appendSubPart(part); + tree->d->appendSubPart(part); } else if (text) { auto part = std::make_shared(); part->d->fillFrom(text); - mTree->d->appendSubPart(part); + tree->d->appendSubPart(part); } else if (alternative) { auto part = std::make_shared(); part->d->fillFrom(alternative); - mTree->d->appendSubPart(part); + tree->d->appendSubPart(part); } else if (html) { auto part = std::make_shared(); part->d->fillFrom(html); - mTree->d->appendSubPart(part); + tree->d->appendSubPart(part); } else { - createTree(m, tree); + const auto enc = mp.dynamicCast(); + const auto sig = mp.dynamicCast(); + if (enc || sig) { + auto subTree = std::make_shared(); + if (enc) { + subTree->d->appendEncryption(enc); + } + if (sig) { + subTree->d->appendSignature(sig); + } + createTree(m, subTree); + foreach(const auto &p, subTree->subParts()) { + tree->d->appendSubPart(p); + if (enc) { + p->d->setEncryptions(subTree->d->encryptions()); + } + if (sig) { + p->d->setSignatures(subTree->d->signatures()); + } + } + } else { + createTree(m, tree); + } } } } -- cgit v1.2.3 From 349e404b539c1f9d1feb54658e2e6fbbd2165462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Wed, 10 Aug 2016 13:20:11 +0200 Subject: Use new mimetreeparser interface --- framework/domain/mimetreeparser/interface.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'framework/domain/mimetreeparser/interface.cpp') 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() { } +QUrl Parser::getPart(const QByteArray &cid) +{ + return d->mEmbeddedPartMap.value(cid); +} + QVector Parser::collectContentParts() const { return collect(d->mTree, [](const Part::Ptr &p){return p->type() != "EncapsulatedPart";}, -- cgit v1.2.3 From 1974c19eadd497e355ac985a00d0571f3e6c7712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Tue, 11 Oct 2016 16:18:50 +0200 Subject: create model for new mailviewer --- framework/domain/mimetreeparser/interface.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') 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 @@ #include #include +#include #include class MailMimePrivate @@ -356,6 +357,17 @@ QByteArray Content::charset() const return d->mCodec; } +QString Content::encodedContent() const +{ + return encodedContent(charset()); +} + +QString Content::encodedContent(const QByteArray &charset) const +{ + QTextCodec *codec = QTextCodec::codecForName(charset); + return codec->toUnicode(content()); +} + QByteArray Content::type() const { return "Content"; @@ -496,7 +508,7 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) mContent.clear(); foreach (const auto &mp, part->subParts()) { auto d_ptr = new ContentPrivate; - d_ptr->mContent = part->text().toLocal8Bit(); + d_ptr->mContent = mp->text().toLocal8Bit(); d_ptr->mParent = q; d_ptr->mCodec = "utf-8"; const auto enc = mp.dynamicCast(); -- cgit v1.2.3 From b40e6c476e54c5dab834c4d01936d1f7bc33c60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Wed, 12 Oct 2016 16:41:00 +0200 Subject: Make nested mails work with mailviewer --- framework/domain/mimetreeparser/interface.cpp | 50 +++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index efa0fd40..596dc152 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -36,14 +36,24 @@ class MailMimePrivate { public: - KMime::Content *mNode; + MailMimePrivate(MailMime *p); + MailMime *q; + KMime::Content *mNode; + std::shared_ptr parent; }; +MailMimePrivate::MailMimePrivate(MailMime* p) + : q(p) + , mNode(nullptr) + , parent(nullptr) +{ +} + + MailMime::MailMime() - : d(std::unique_ptr(new MailMimePrivate())) + : d(std::unique_ptr(new MailMimePrivate(this))) { - d->q = this; } bool MailMime::isFirstTextPart() const @@ -54,6 +64,14 @@ bool MailMime::isFirstTextPart() const return (d->mNode->topLevel()->textContent() == d->mNode); } +bool MailMime::isFirstPart() const +{ + if (!d->mNode || !d->mNode->parent()) { + return false; + } + return (d->mNode->parent()->contents().first() == d->mNode); +} + bool MailMime::isTopLevelPart() const { if (!d->mNode) { @@ -108,6 +126,15 @@ QMimeType MailMime::mimetype() const return mimeDb.mimeTypeForName(ct->mimeType()); } +MailMime::Ptr MailMime::parent() const +{ + if (!d->parent) { + d->parent = std::shared_ptr(new MailMime()); + d->parent->d->mNode = d->mNode->parent(); + } + return d->parent; +} + class PartPrivate { public: @@ -285,6 +312,11 @@ MailMime::Ptr Part::mailMime() const return d->mailMime(); } +Part *Part::parent() const +{ + return d->parent(); +} + class ContentPrivate { public: @@ -738,12 +770,16 @@ QVector Parser::collectContentParts() const } { - const auto parent = content->parent(); - if (parent) { - const auto _mime = parent->mailMime(); + auto _mime = content->parent()->mailMime(); + while (_mime) { if (_mime && (_mime->isTopLevelPart() || _mime->isFirstTextPart())) { return true; } + if (_mime->isFirstPart()) { + _mime = _mime->parent(); + } else { + break; + } } } const auto cd = mime->disposition(); @@ -830,4 +866,4 @@ QVector Parser::collect(const Part::Ptr &start, std::function Date: Mon, 17 Oct 2016 12:24:32 +0200 Subject: do not include multipart/related in attachmentlist --- framework/domain/mimetreeparser/interface.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index 596dc152..ab56f800 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -818,12 +818,24 @@ QVector Parser::collectAttachmentParts() const } { - const auto parent = content->parent(); + QMimeDatabase mimeDb; + auto _mime = content->parent()->mailMime(); + const auto parent = _mime->parent(); if (parent) { - const auto _mime = parent->mailMime(); + const auto mimetype = parent->mimetype(); + if (mimetype == mimeDb.mimeTypeForName("multipart/related")) { + return false; + } + } + while (_mime) { if (_mime && (_mime->isTopLevelPart() || _mime->isFirstTextPart())) { return false; } + if (_mime->isFirstPart()) { + _mime = _mime->parent(); + } else { + break; + } } } const auto cd = mime->disposition(); -- cgit v1.2.3 From b7a02699eefd84c68ff602bfea91640faec5c4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Mon, 17 Oct 2016 13:05:43 +0200 Subject: find part by cid --- framework/domain/mimetreeparser/interface.cpp | 34 +++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index ab56f800..c2fd1e65 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -56,6 +56,14 @@ MailMime::MailMime() { } +QByteArray MailMime::cid() const +{ + if (!d->mNode || !d->mNode->contentID()) { + return QByteArray(); + } + return d->mNode->contentID()->identifier(); +} + bool MailMime::isFirstTextPart() const { if (!d->mNode || !d->mNode->topLevel()) { @@ -750,9 +758,16 @@ Parser::~Parser() { } -QUrl Parser::getPart(const QByteArray &cid) +Part::Ptr Parser::getPart(const QUrl &url) { - return d->mEmbeddedPartMap.value(cid); + if (url.scheme() == QStringLiteral("cid") && !url.path().isEmpty()) { + const auto cid = url.path(); + return find(d->mTree, [&cid](const Part::Ptr &p){ + const auto mime = p->mailMime(); + return mime->cid() == cid; + }); + } + return Part::Ptr(); } QVector Parser::collectContentParts() const @@ -857,6 +872,7 @@ QVector Parser::collectAttachmentParts() const return true; }); } + QVector Parser::collect(const Part::Ptr &start, std::function select, std::function filter) const { QVector ret; @@ -879,3 +895,17 @@ QVector Parser::collect(const Part::Ptr &start, std::function select) const +{ + foreach (const auto &part, start->subParts()) { + if (select(part)) { + return part; + } + const auto ret = find(part, select); + if (ret) { + return ret; + } + } + return Part::Ptr(); +} -- cgit v1.2.3 From 1fe0ab05ae2bfe6505736f598bd535a71fb86a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Mon, 17 Oct 2016 15:35:49 +0200 Subject: replace cid links with actuall content of the images --- framework/domain/mimetreeparser/interface.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index c2fd1e65..b5e29e6b 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -143,6 +143,15 @@ MailMime::Ptr MailMime::parent() const return d->parent; } +QByteArray MailMime::decodedContent() const +{ + if (!d->mNode) { + return QByteArray(); + } + return d->mNode->decodedContent(); +} + + class PartPrivate { public: @@ -581,7 +590,7 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::AttachmentMessagePart::Ptr part q->reachParentD()->createMailMime(part.staticCast()); mType = q->mailMime()->mimetype().name().toUtf8(); mContent.clear(); - mContent.append(std::make_shared(part->text().toLocal8Bit(), q)); + mContent.append(std::make_shared(q->mailMime()->decodedContent(), q)); } SinglePart::SinglePart() -- cgit v1.2.3 From 5cb20dd3886ee229d74068c75250691c840e89a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Mon, 17 Oct 2016 16:33:03 +0200 Subject: Read correct charset out of mailpart --- framework/domain/mimetreeparser/interface.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index b5e29e6b..ceb8caf3 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -64,6 +64,17 @@ QByteArray MailMime::cid() const return d->mNode->contentID()->identifier(); } +QByteArray MailMime::charset() const +{ + if(!d->mNode || !d->mNode->contentType(false)) { + return QByteArray(); + } + if (d->mNode->contentType(false)) { + return d->mNode->contentType(false)->charset(); + } + return d->mNode->defaultCharset(); +} + bool MailMime::isFirstTextPart() const { if (!d->mNode || !d->mNode->topLevel()) { @@ -559,7 +570,6 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) auto d_ptr = new ContentPrivate; d_ptr->mContent = mp->text().toLocal8Bit(); d_ptr->mParent = q; - d_ptr->mCodec = "utf-8"; const auto enc = mp.dynamicCast(); auto sig = mp.dynamicCast(); if (enc) { @@ -574,6 +584,7 @@ void SinglePartPrivate::fillFrom(MimeTreeParser::TextMessagePart::Ptr part) } mContent.append(std::make_shared(d_ptr)); q->reachParentD()->createMailMime(part); + d_ptr->mCodec = q->mailMime()->charset(); } } -- cgit v1.2.3 From d15a02d3c26c24530e8d9360629212e419c81c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20Knau=C3=9F?= Date: Mon, 17 Oct 2016 19:06:12 +0200 Subject: fill Encryption and Signatures with content --- framework/domain/mimetreeparser/interface.cpp | 262 +++++++++++++++++++++----- 1 file changed, 210 insertions(+), 52 deletions(-) (limited to 'framework/domain/mimetreeparser/interface.cpp') diff --git a/framework/domain/mimetreeparser/interface.cpp b/framework/domain/mimetreeparser/interface.cpp index ceb8caf3..0bcbfec4 100644 --- a/framework/domain/mimetreeparser/interface.cpp +++ b/framework/domain/mimetreeparser/interface.cpp @@ -23,6 +23,10 @@ #include "stringhtmlwriter.h" #include "objecttreesource.h" +#include +#include +#include + #include #include #include @@ -162,6 +166,131 @@ QByteArray MailMime::decodedContent() const return d->mNode->decodedContent(); } +class KeyPrivate +{ +public: + Key *q; + GpgME::Key mKey; +}; + +Key::Key() + :d(std::unique_ptr(new KeyPrivate)) +{ + d->q = this; +} + + +Key::Key(KeyPrivate *d_ptr) + :d(std::unique_ptr(d_ptr)) +{ + d->q = this; +} + +Key::~Key() +{ + +} + +QString Key::keyid() const +{ + return d->mKey.keyID(); +} + +QString Key::name() const +{ + //FIXME: is this the correct way to get the primary UID? + return d->mKey.userID(0).name(); +} + +QString Key::email() const +{ + return d->mKey.userID(0).email(); +} + +QString Key::comment() const +{ + return d->mKey.userID(0).comment(); +} + +class SignaturePrivate +{ +public: + Signature *q; + GpgME::Signature mSignature; + Key::Ptr mKey; +}; + +Signature::Signature() + :d(std::unique_ptr(new SignaturePrivate)) +{ + d->q = this; +} + + +Signature::Signature(SignaturePrivate *d_ptr) + :d(std::unique_ptr(d_ptr)) +{ + d->q = this; + +} + +Signature::~Signature() +{ + +} + +QDateTime Signature::creationDateTime() const +{ + QDateTime dt; + dt.setTime_t(d->mSignature.creationTime()); + return dt; +} + +QDateTime Signature::expirationDateTime() const +{ + QDateTime dt; + dt.setTime_t(d->mSignature.expirationTime()); + return dt; +} + +bool Signature::neverExpires() const +{ + return d->mSignature.neverExpires(); +} + +Key::Ptr Signature::key() const +{ + return d->mKey; +} + +class EncryptionPrivate +{ +public: + Encryption *q; + std::vector mRecipients; +}; + +Encryption::Encryption(EncryptionPrivate *d_ptr) + :d(std::unique_ptr(d_ptr)) +{ + d->q = this; +} + +Encryption::Encryption() + :d(std::unique_ptr(new EncryptionPrivate)) +{ + d->q = this; +} + +Encryption::~Encryption() +{ + +} + +std::vector Encryption::recipients() const +{ + return d->mRecipients; +} class PartPrivate { @@ -179,7 +308,9 @@ public: void createMailMime(const MimeTreeParser::AlternativeMessagePart::Ptr &part); void createMailMime(const MimeTreeParser::HtmlMessagePart::Ptr &part); + static Encryption::Ptr createEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part); void appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr &part); + static QVector createSignature(const MimeTreeParser::SignedMessagePart::Ptr& part); void appendSignature(const MimeTreeParser::SignedMessagePart::Ptr &part); void setSignatures(const QVector &sigs); @@ -233,9 +364,43 @@ void PartPrivate::appendSubPart(Part::Ptr subpart) mSubParts.append(subpart); } +Encryption::Ptr PartPrivate::createEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part) +{ + Kleo::KeyListJob *job = part->mCryptoProto->keyListJob(false); // local, no sigs + if (!job) { + qWarning() << "The Crypto backend does not support listing keys. "; + return Encryption::Ptr(); + } + + auto encpriv = new EncryptionPrivate(); + foreach(const auto &recipient, part->mDecryptRecipients) { + std::vector found_keys; + const auto &keyid = recipient.keyID(); + GpgME::KeyListResult res = job->exec(QStringList(QLatin1String(keyid)), false, found_keys); + if (res.error()) { + qWarning() << "Error while searching key for Fingerprint: " << keyid; + continue; + } + if (found_keys.size() > 1) { + // Should not Happen + qWarning() << "Oops: Found more then one Key for Fingerprint: " << keyid; + } + if (found_keys.size() != 1) { + // Should not Happen at this point + qWarning() << "Oops: Found no Key for Fingerprint: " << keyid; + } else { + auto key = found_keys[0]; + auto keypriv = new KeyPrivate; + keypriv->mKey = key; + encpriv->mRecipients.push_back(Key::Ptr(new Key(keypriv))); + } + } + return Encryption::Ptr(new Encryption(encpriv)); +} + void PartPrivate::appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& part) { - mEncryptions.append(Encryption::Ptr(new Encryption)); + mEncryptions.append(createEncryption(part)); } void PartPrivate::setEncryptions(const QVector< Encryption::Ptr >& encs) @@ -243,9 +408,50 @@ void PartPrivate::setEncryptions(const QVector< Encryption::Ptr >& encs) mEncryptions = encs; } +QVector PartPrivate::createSignature(const MimeTreeParser::SignedMessagePart::Ptr& part) +{ + QVector sigs; + Kleo::KeyListJob *job = part->mCryptoProto->keyListJob(false); // local, no sigs + if (!job) { + qWarning() << "The Crypto backend does not support listing keys. "; + return sigs; + } + + foreach(const auto &sig, part->mSignatures) { + auto sigpriv = new SignaturePrivate(); + sigpriv->mSignature = sig; + auto signature = std::make_shared(sigpriv); + sigs.append(signature); + + std::vector found_keys; + const auto &keyid = sig.fingerprint(); + GpgME::KeyListResult res = job->exec(QStringList(QLatin1String(keyid)), false, found_keys); + if (res.error()) { + qWarning() << "Error while searching key for Fingerprint: " << keyid; + continue; + } + if (found_keys.size() > 1) { + // Should not Happen + qWarning() << "Oops: Found more then one Key for Fingerprint: " << keyid; + continue; + } + if (found_keys.size() != 1) { + // Should not Happen at this point + qWarning() << "Oops: Found no Key for Fingerprint: " << keyid; + continue; + } else { + auto key = found_keys[0]; + auto keypriv = new KeyPrivate; + keypriv->mKey = key; + sigpriv->mKey = Key::Ptr(new Key(keypriv)); + } + } + return sigs; +} + void PartPrivate::appendSignature(const MimeTreeParser::SignedMessagePart::Ptr& part) { - mSignatures.append(Signature::Ptr(new Signature)); + mSignatures.append(createSignature(part)); } @@ -361,12 +567,12 @@ public: void ContentPrivate::appendEncryption(const MimeTreeParser::EncryptedMessagePart::Ptr& enc) { - mEncryptions.append(Encryption::Ptr(new Encryption)); + mEncryptions.append(PartPrivate::createEncryption(enc)); } void ContentPrivate::appendSignature(const MimeTreeParser::SignedMessagePart::Ptr& sig) { - mSignatures.append(Signature::Ptr(new Signature)); + mSignatures.append(PartPrivate::createSignature(sig)); } @@ -638,54 +844,6 @@ PartPrivate* SinglePart::reachParentD() const return Part::d.get(); } -class SignaturePrivate -{ -public: - Signature *q; -}; - -Signature::Signature() - :d(std::unique_ptr(new SignaturePrivate)) -{ - d->q = this; -} - - -Signature::Signature(SignaturePrivate *d_ptr) - :d(std::unique_ptr(d_ptr)) -{ - d->q = this; -} - -Signature::~Signature() -{ - -} - - -class EncryptionPrivate -{ -public: - Encryption *q; -}; - -Encryption::Encryption(EncryptionPrivate *d_ptr) - :d(std::unique_ptr(d_ptr)) -{ - d->q = this; -} - -Encryption::Encryption() - :d(std::unique_ptr(new EncryptionPrivate)) -{ - d->q = this; -} - -Encryption::~Encryption() -{ - -} - ParserPrivate::ParserPrivate(Parser* parser) : q(parser) , mNodeHelper(std::make_shared()) -- cgit v1.2.3