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 
19 #include <KEmailAddress>
20 #include <KMime/KMimeMessage>
21 
22 using namespace MessageComposer;
23 
24 class MessageComposer::SkeletonMessageJobPrivate : public JobBasePrivate
25 {
26 public:
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 
41 void SkeletonMessageJobPrivate::doStart()
42 {
43  Q_Q(SkeletonMessageJob);
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")), "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), "utf-8");
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), "utf-8");
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), "utf-8");
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), "utf-8");
123  message->setHeader(bcc);
124  }
125 
126  // Subject:
127  {
128  auto subject = new KMime::Headers::Subject;
129  subject->fromUnicodeString(infoPart->subject(), "utf-8");
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(), "utf-8");
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()), "utf-8");
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, "utf-8");
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, "utf-8");
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)"), "utf-8");
211  auto urg2 = new KMime::Headers::Generic("Priority");
212  urg2->fromUnicodeString(QStringLiteral("urgent"), "utf-8");
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(), "utf-8");
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(), "utf-8");
228  message->setHeader(header);
229  }
230 
231  q->emitResult(); // Success.
232 }
233 
234 SkeletonMessageJob::SkeletonMessageJob(InfoPart *infoPart, GlobalPart *globalPart, QObject *parent)
235  : JobBase(*new SkeletonMessageJobPrivate(this), parent)
236 {
238  d->infoPart = infoPart;
239  d->globalPart = globalPart;
240 }
241 
242 SkeletonMessageJob::~SkeletonMessageJob() = default;
243 
244 InfoPart *SkeletonMessageJob::infoPart() const
245 {
246  Q_D(const SkeletonMessageJob);
247  return d->infoPart;
248 }
249 
250 void SkeletonMessageJob::setInfoPart(InfoPart *part)
251 {
253  d->infoPart = part;
254 }
255 
256 GlobalPart *SkeletonMessageJob::globalPart() const
257 {
258  Q_D(const SkeletonMessageJob);
259  return d->globalPart;
260 }
261 
262 void SkeletonMessageJob::setGlobalPart(GlobalPart *part)
263 {
265  d->globalPart = part;
266 }
267 
268 KMime::Message *SkeletonMessageJob::message() const
269 {
270  Q_D(const SkeletonMessageJob);
271  return d->message;
272 }
273 
274 void SkeletonMessageJob::start()
275 {
277  d->doStart();
278 }
279 
280 #include "moc_skeletonmessagejob.cpp"
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
QString number(int n, int base)
QByteArray & append(char ch)
QDateTime currentDateTime()
A dummy abstract class defining some errors pertaining to the Composer.
Definition: jobbase.h:24
QByteArray toAce(const QString &domain)
The GlobalPart class.
Definition: globalpart.h:19
A message containing only the headers...
bool isEmpty() const const
void setDateTime(const QDateTime &dt)
void fromUnicodeString(const QString &s, const QByteArray &b) override
The InfoPart class contains the message header.
Definition: infopart.h:21
PostalAddress address(const QVariant &location)
bool isEmpty() const const
QString localHostName()
QString fromLatin1(const char *str, int size)
void fromUnicodeString(const QString &s, const QByteArray &b) override
QString message
Q_D(Todo)
KCODECS_EXPORT QString normalizeAddressesAndEncodeIdn(const QString &str)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Mar 27 2023 04:08:18 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.