Messagelib

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

KDE's Doxygen guidelines are available online.