messagehelper.cpp 5.87 KB
Newer Older
1
/*
2
3
  SPDX-FileCopyrightText: 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
  SPDX-FileCopyrightText: 2009 Andras Mantia <andras@kdab.net>
4

5
  SPDX-License-Identifier: GPL-2.0-or-later
6
7
8
9
*/

#include "messagehelper.h"
#include "settings/messagecomposersettings.h"
Laurent Montel's avatar
Laurent Montel committed
10
#include "utils/util.h"
11
12
13
14

#include "MessageCore/MailingList"
#include "MessageCore/StringUtil"

Laurent Montel's avatar
Laurent Montel committed
15
#include "messagecomposer_debug.h"
16
17
#include <KMime/Message>
#include <kidentitymanagement/identity.h>
Laurent Montel's avatar
Laurent Montel committed
18
19
20
#include <kidentitymanagement/identitymanager.h>
#include <kmime/kmime_dateformatter.h>
#include <kmime/kmime_mdn.h>
21
22
23

using namespace MessageCore;

Laurent Montel's avatar
Laurent Montel committed
24
25
namespace MessageHelper
{
26
27
28
29
30
31
32
33
34
35
36
void initHeader(const KMime::Message::Ptr &message, const KIdentityManagement::IdentityManager *identMan, uint id)
{
    applyIdentity(message, identMan, id);
    message->removeHeader<KMime::Headers::To>();
    message->removeHeader<KMime::Headers::Subject>();
    message->date()->setDateTime(QDateTime::currentDateTime());

    // This will allow to change Content-Type:
    message->contentType()->setMimeType("text/plain");
}

Laurent Montel's avatar
Laurent Montel committed
37
38
39
40
41
void initFromMessage(const KMime::Message::Ptr &msg,
                     const KMime::Message::Ptr &origMsg,
                     KIdentityManagement::IdentityManager *identMan,
                     uint id,
                     bool idHeaders)
42
43
44
45
{
    if (idHeaders) {
        MessageHelper::initHeader(msg, identMan, id);
    } else {
Laurent Montel's avatar
Laurent Montel committed
46
        auto header = new KMime::Headers::Generic("X-KMail-Identity");
47
48
49
50
51
52
        header->fromUnicodeString(QString::number(id), "utf-8");
        msg->setHeader(header);
    }

    if (auto hdr = origMsg->headerByType("X-KMail-Transport")) {
        const QString transport = hdr->asUnicodeString();
Laurent Montel's avatar
Laurent Montel committed
53
        auto header = new KMime::Headers::Generic("X-KMail-Transport");
54
55
56
57
58
59
60
        header->fromUnicodeString(transport, "utf-8");
        msg->setHeader(header);
    }
}

void applyIdentity(const KMime::Message::Ptr &message, const KIdentityManagement::IdentityManager *identMan, uint id)
{
Laurent Montel's avatar
Laurent Montel committed
61
    const KIdentityManagement::Identity &ident = identMan->identityForUoidOrDefault(id);
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

    if (ident.fullEmailAddr().isEmpty()) {
        message->removeHeader<KMime::Headers::From>();
    } else {
        message->from()->addAddress(ident.primaryEmailAddress().toUtf8(), ident.fullName());
    }

    if (ident.replyToAddr().isEmpty()) {
        message->removeHeader<KMime::Headers::ReplyTo>();
    } else {
        message->replyTo()->addAddress(ident.replyToAddr().toUtf8());
    }

    if (ident.bcc().isEmpty()) {
        message->removeHeader<KMime::Headers::Bcc>();
    } else {
        const auto mailboxes = KMime::Types::Mailbox::listFromUnicodeString(ident.bcc());
Laurent Montel's avatar
Laurent Montel committed
79
        for (const KMime::Types::Mailbox &mailbox : mailboxes) {
80
81
82
83
84
85
86
87
            message->bcc()->addAddress(mailbox);
        }
    }

    if (ident.cc().isEmpty()) {
        message->removeHeader<KMime::Headers::Cc>();
    } else {
        const auto mailboxes = KMime::Types::Mailbox::listFromUnicodeString(ident.cc());
Laurent Montel's avatar
Laurent Montel committed
88
        for (const KMime::Types::Mailbox &mailbox : mailboxes) {
89
90
91
92
93
94
95
            message->cc()->addAddress(mailbox);
        }
    }

    if (ident.organization().isEmpty()) {
        message->removeHeader<KMime::Headers::Organization>();
    } else {
Laurent Montel's avatar
Laurent Montel committed
96
        auto const organization = new KMime::Headers::Organization;
97
98
99
100
101
102
103
        organization->fromUnicodeString(ident.organization(), "utf-8");
        message->setHeader(organization);
    }

    if (ident.isDefault()) {
        message->removeHeader("X-KMail-Identity");
    } else {
Laurent Montel's avatar
Laurent Montel committed
104
        auto header = new KMime::Headers::Generic("X-KMail-Identity");
105
106
107
108
109
110
111
        header->fromUnicodeString(QString::number(ident.uoid()), "utf-8");
        message->setHeader(header);
    }

    if (ident.transport().isEmpty()) {
        message->removeHeader("X-KMail-Transport");
    } else {
Laurent Montel's avatar
Laurent Montel committed
112
        auto header = new KMime::Headers::Generic("X-KMail-Transport");
113
114
115
116
117
118
119
        header->fromUnicodeString(ident.transport(), "utf-8");
        message->setHeader(header);
    }

    if (ident.fcc().isEmpty()) {
        message->removeHeader("X-KMail-Fcc");
    } else {
Laurent Montel's avatar
Laurent Montel committed
120
        auto header = new KMime::Headers::Generic("X-KMail-Fcc");
121
122
123
124
125
        header->fromUnicodeString(ident.fcc(), "utf-8");
        message->setHeader(header);
    }

    if (ident.disabledFcc()) {
Laurent Montel's avatar
Laurent Montel committed
126
        auto header = new KMime::Headers::Generic("X-KMail-FccDisabled");
127
128
129
130
131
132
133
134
135
136
        header->fromUnicodeString(QStringLiteral("true"), "utf-8");
        message->setHeader(header);
    } else {
        message->removeHeader("X-KMail-FccDisabled");
    }
}

KMime::Types::AddrSpecList extractAddrSpecs(const KMime::Message::Ptr &msg, const QByteArray &header)
{
    KMime::Types::AddrSpecList result;
Laurent Montel's avatar
Laurent Montel committed
137
    if (auto hrd = msg->headerByType(header.constData())) {
138
139
140
        // Don't use "asUnicodeString().toUtf8()" it removes \" from \"foo, bla\" <foo@kde.org> => send failed
        // Bug 439218
        KMime::Types::AddressList al = MessageCore::StringUtil::splitAddressField(hrd->as7BitString(false));
Laurent Montel's avatar
Laurent Montel committed
141
142
143
144
145
146
        KMime::Types::AddressList::const_iterator alend(al.constEnd());
        for (KMime::Types::AddressList::const_iterator ait = al.constBegin(); ait != alend; ++ait) {
            KMime::Types::MailboxList::const_iterator mitEnd((*ait).mailboxList.constEnd());
            for (KMime::Types::MailboxList::const_iterator mit = (*ait).mailboxList.constBegin(); mit != mitEnd; ++mit) {
                result.push_back((*mit).addrSpec());
            }
147
148
149
150
151
152
153
154
155
156
157
158
        }
    }
    return result;
}

void setAutomaticFields(const KMime::Message::Ptr &msg, bool aIsMulti)
{
    auto header = msg->header<KMime::Headers::MIMEVersion>(true);
    header->from7BitString("1.0");

    if (aIsMulti || msg->contents().size() > 1) {
        // Set the type to 'Multipart' and the subtype to 'Mixed'
159
        msg->contentType(false)->setMimeType("multipart/mixed");
160
        // Create a random printable string and set it as the boundary parameter
161
        msg->contentType(false)->setBoundary(KMime::multiPartBoundary());
162
163
164
    }
}
}