Messagelib

skeletonmessagejob.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "job/skeletonmessagejob.h"
8#include "settings/messagecomposersettings.h"
9
10#include "job/jobbase_p.h"
11#include "part/globalpart.h"
12#include "part/infopart.h"
13
14#include <QHostInfo>
15#include <QUrl>
16
17#include "messagecomposer_debug.h"
18
19#include <KEmailAddress>
20#include <KMime/Message>
21
22using namespace MessageComposer;
23
24class MessageComposer::SkeletonMessageJobPrivate : public JobBasePrivate
25{
26public:
27 SkeletonMessageJobPrivate(SkeletonMessageJob *qq)
28 : JobBasePrivate(qq)
29 {
30 }
31
32 void doStart(); // slot
33
34 InfoPart *infoPart = nullptr;
35 GlobalPart *globalPart = nullptr;
36 KMime::Message *message = nullptr;
37
38 Q_DECLARE_PUBLIC(SkeletonMessageJob)
39};
40
41void SkeletonMessageJobPrivate::doStart()
42{
44
45 Q_ASSERT(infoPart);
46 Q_ASSERT(message == nullptr);
47 message = new KMime::Message;
48
49 // From:
50 {
51 auto from = new KMime::Headers::From;
53 address.fromUnicodeString(KEmailAddress::normalizeAddressesAndEncodeIdn(infoPart->from()));
54 from->fromUnicodeString(QString::fromLatin1(address.as7BitString("utf-8")));
55 message->setHeader(from);
56 }
57
58 // To:
59 {
60 auto to = new KMime::Headers::To;
61 QByteArray sTo;
62 const QStringList lstTo = infoPart->to();
63 for (const QString &a : lstTo) {
66 if (!sTo.isEmpty()) {
67 sTo.append(",");
68 }
69 sTo.append(address.as7BitString("utf-8"));
70 }
71 to->fromUnicodeString(QString::fromLatin1(sTo));
72 message->setHeader(to);
73 }
74
75 // Reply To:
76 if (!infoPart->replyTo().isEmpty()) {
77 auto replyTo = new KMime::Headers::ReplyTo;
78 const QStringList lstReplyTo = infoPart->replyTo();
79 QByteArray sReplyTo;
80 for (const QString &a : lstReplyTo) {
83 if (!sReplyTo.isEmpty()) {
84 sReplyTo.append(",");
85 }
86 sReplyTo.append(address.as7BitString("utf-8"));
87 }
88 replyTo->fromUnicodeString(QString::fromLatin1(sReplyTo));
89 message->setHeader(replyTo);
90 }
91
92 // Cc:
93 {
94 auto cc = new KMime::Headers::Cc;
95 QByteArray sCc;
96 const QStringList lstCc = infoPart->cc();
97 for (const QString &a : lstCc) {
100 if (!sCc.isEmpty()) {
101 sCc.append(",");
102 }
103 sCc.append(address.as7BitString("utf-8"));
104 }
105 cc->fromUnicodeString(QString::fromLatin1(sCc));
106 message->setHeader(cc);
107 }
108
109 // Bcc:
110 {
111 auto bcc = new KMime::Headers::Bcc;
112 QByteArray sBcc;
113 const QStringList lstBcc = infoPart->bcc();
114 for (const QString &a : lstBcc) {
117 if (!sBcc.isEmpty()) {
118 sBcc.append(",");
119 }
120 sBcc.append(address.as7BitString("utf-8"));
121 }
122 bcc->fromUnicodeString(QString::fromLatin1(sBcc));
123 message->setHeader(bcc);
124 }
125
126 // Subject:
127 {
128 auto subject = new KMime::Headers::Subject;
129 subject->fromUnicodeString(infoPart->subject());
130 // TODO should we be more specific about the charset?
131 message->setHeader(subject);
132 }
133
134 // Date:
135 {
136 auto date = new KMime::Headers::Date;
138 message->setHeader(date);
139 }
140
141 // Fcc:
142 if (!infoPart->fcc().isEmpty()) {
143 auto header = new KMime::Headers::Generic("X-KMail-Fcc");
144 header->fromUnicodeString(infoPart->fcc());
145 message->setHeader(header);
146 }
147
148 // Transport:
149 if (infoPart->transportId() > -1) {
150 auto header = new KMime::Headers::Generic("X-KMail-Transport");
151 header->fromUnicodeString(QString::number(infoPart->transportId()));
152 message->setHeader(header);
153 }
154
155 // Message-ID
156 {
157 auto messageId = new KMime::Headers::MessageID();
158 QByteArray fqdn;
159 if (MessageComposer::MessageComposerSettings::self()->useCustomMessageIdSuffix()) {
160 fqdn = QUrl::toAce(MessageComposer::MessageComposerSettings::self()->customMsgIDSuffix());
161 }
162 if (fqdn.isEmpty()) {
164 }
165 if (fqdn.isEmpty()) {
166 qCWarning(MESSAGECOMPOSER_LOG) << "Unable to generate a Message-ID, falling back to 'localhost.localdomain'.";
167 fqdn = "local.domain";
168 }
169 messageId->generate(fqdn);
170 message->setHeader(messageId);
171 }
172 // Extras
173
174 const KMime::Headers::Base::List extraHeaders = infoPart->extraHeaders();
175 for (KMime::Headers::Base *extra : extraHeaders) {
176 const QByteArray headerType(extra->type());
177 auto copyHeader = KMime::Headers::createHeader(headerType);
178 if (!copyHeader) {
179 copyHeader = new KMime::Headers::Generic(headerType.constData(), headerType.size());
180 }
181 copyHeader->from7BitString(extra->as7BitString(false));
182 message->setHeader(copyHeader);
183 }
184
185 // Request Delivery Confirmation
186 {
187 if (globalPart->requestDeleveryConfirmation()) {
188 // TODO fix me multi address
189 const QString addr = infoPart->replyTo().isEmpty() ? infoPart->from() : infoPart->replyTo().at(0);
190 auto requestDeleveryConfirmation = new KMime::Headers::Generic("Return-Receipt-To");
191 requestDeleveryConfirmation->fromUnicodeString(addr);
192 message->setHeader(requestDeleveryConfirmation);
193 }
194 }
195
196 // MDN
197 {
198 if (globalPart->MDNRequested()) {
199 // TODO fix me multi address
200 const QString addr = infoPart->replyTo().isEmpty() ? infoPart->from() : infoPart->replyTo().at(0);
201 auto mdn = new KMime::Headers::Generic("Disposition-Notification-To");
202 mdn->fromUnicodeString(addr);
203 message->setHeader(mdn);
204 }
205 }
206
207 // Urgent header
208 if (infoPart->urgent()) {
209 auto urg1 = new KMime::Headers::Generic("X-PRIORITY");
210 urg1->fromUnicodeString(QStringLiteral("2 (High)"));
211 auto urg2 = new KMime::Headers::Generic("Priority");
212 urg2->fromUnicodeString(QStringLiteral("urgent"));
213 message->setHeader(urg1);
214 message->setHeader(urg2);
215 }
216
217 // In-Reply-To
218 if (!infoPart->inReplyTo().isEmpty()) {
219 auto header = new KMime::Headers::InReplyTo;
220 header->fromUnicodeString(infoPart->inReplyTo());
221 message->setHeader(header);
222 }
223
224 // References
225 if (!infoPart->references().isEmpty()) {
226 auto header = new KMime::Headers::References;
227 header->fromUnicodeString(infoPart->references());
228 message->setHeader(header);
229 }
230
231 q->emitResult(); // Success.
232}
233
234SkeletonMessageJob::SkeletonMessageJob(InfoPart *infoPart, GlobalPart *globalPart, QObject *parent)
235 : JobBase(*new SkeletonMessageJobPrivate(this), parent)
236{
238 d->infoPart = infoPart;
239 d->globalPart = globalPart;
240}
241
242SkeletonMessageJob::~SkeletonMessageJob() = default;
243
244InfoPart *SkeletonMessageJob::infoPart() const
245{
246 Q_D(const SkeletonMessageJob);
247 return d->infoPart;
248}
249
250void SkeletonMessageJob::setInfoPart(InfoPart *part)
251{
253 d->infoPart = part;
254}
255
256GlobalPart *SkeletonMessageJob::globalPart() const
257{
258 Q_D(const SkeletonMessageJob);
259 return d->globalPart;
260}
261
262void SkeletonMessageJob::setGlobalPart(GlobalPart *part)
263{
265 d->globalPart = part;
266}
267
268KMime::Message *SkeletonMessageJob::message() const
269{
270 Q_D(const SkeletonMessageJob);
271 return d->message;
272}
273
274void SkeletonMessageJob::start()
275{
277 d->doStart();
278}
279
280#include "moc_skeletonmessagejob.cpp"
void setHeader(Headers::Base *h)
void setDateTime(const QDateTime &dt)
void fromUnicodeString(const QString &s) override
void fromUnicodeString(const QString &s) override
The GlobalPart class.
Definition globalpart.h:20
The InfoPart class contains the message header.
Definition infopart.h:22
QStringList replyTo
Reply-To: Email address that should be used to reply to this mail.
Definition infopart.h:39
QStringList cc
Carbon copy: The email address and optionally the name of the secondary recipients.
Definition infopart.h:32
QString inReplyTo
In-Reply-To: Id of the message this message is a reply to.
Definition infopart.h:54
QString from
The email address and optionally the name of the author of the mail.
Definition infopart.h:26
QStringList to
The email address and optionally the name of the primary recipients.
Definition infopart.h:29
QString subject
Subject of the message.
Definition infopart.h:42
QString fcc
The name of a file, to which a copy of the sent message should be appended.
Definition infopart.h:45
bool urgent
Set urgency of the message.
Definition infopart.h:51
QStringList bcc
Blind Carbon copy: The email address and optionally the name of the secondary recipients.
Definition infopart.h:36
A dummy abstract class defining some errors pertaining to the Composer.
Definition jobbase.h:25
A message containing only the headers...
KCODECS_EXPORT QString normalizeAddressesAndEncodeIdn(const QString &str)
PostalAddress address(const QVariant &location)
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
QByteArray & append(QByteArrayView data)
bool isEmpty() const const
QDateTime currentDateTime()
QString localHostName()
const_reference at(qsizetype i) const const
bool isEmpty() const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString number(double n, char format, int precision)
QByteArray toAce(const QString &domain, AceProcessingOptions options)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:07:24 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.