Messagelib

attachmentjob.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Constantin Berzan <[email protected]>
3 
4  Parts based on KMail code by:
5  Various authors.
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "job/attachmentjob.h"
11 #include "contentjobbase_p.h"
12 #include "job/singlepartjob.h"
13 #include "part/globalpart.h"
14 #include "utils/util.h"
15 
16 #include "messagecomposer_debug.h"
17 
18 using namespace MessageComposer;
19 using namespace MessageCore;
20 
21 class MessageComposer::AttachmentJobPrivate : public ContentJobBasePrivate
22 {
23 public:
24  AttachmentJobPrivate(AttachmentJob *qq)
25  : ContentJobBasePrivate(qq)
26  {
27  }
28 
30 
31  Q_DECLARE_PUBLIC(AttachmentJob)
32 };
33 
34 AttachmentJob::AttachmentJob(AttachmentPart::Ptr part, QObject *parent)
35  : ContentJobBase(*new AttachmentJobPrivate(this), parent)
36 {
37  Q_D(AttachmentJob);
38  d->part = part;
39 }
40 
41 AttachmentJob::~AttachmentJob() = default;
42 
43 AttachmentPart::Ptr AttachmentJob::attachmentPart() const
44 {
45  Q_D(const AttachmentJob);
46  return d->part;
47 }
48 
49 void AttachmentJob::setAttachmentPart(const AttachmentPart::Ptr &part)
50 {
51  Q_D(AttachmentJob);
52  d->part = part;
53 }
54 
55 void AttachmentJob::doStart()
56 {
57  Q_D(AttachmentJob);
58  Q_ASSERT(d->part);
59 
60  if (d->part->mimeType() == "multipart/digest" || d->part->mimeType() == "message/rfc822") {
61  // this is actually a digest, so we don't want any additional headers
62  // the attachment is really a complete multipart/digest subtype
63  // and us adding our own headers would break it. so copy over the content
64  // and leave it alone
65  auto part = new KMime::Content;
66  part->setContent(d->part->data());
67  part->parse();
68  d->subjobContents << part;
69  process();
70  return;
71  }
72 
73  // Set up a subjob to generate the attachment content.
74  auto sjob = new SinglepartJob(this);
75  sjob->setData(d->part->data());
76 
77  // Figure out a charset to encode parts of the headers with.
78  const QString dataToEncode = d->part->name() + d->part->description() + d->part->fileName();
79  const QByteArray charset = MessageComposer::Util::selectCharset(globalPart()->charsets(true), dataToEncode);
80 
81  // Set up the headers.
82  // rfc822 forwarded messages have 7bit CTE, the message itself will have
83  // its own CTE for the content
84  if (d->part->mimeType() == "message/rfc822") {
85  sjob->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
86  } else {
87  sjob->contentTransferEncoding()->setEncoding(d->part->encoding());
88  }
89 
90  auto ct = sjob->contentType();
91  ct->setMimeType(d->part->mimeType()); // setMimeType() clears all other params.
92  ct->setName(d->part->name(), charset);
93  if (ct->isText()) {
94  // If it is a text file, detect its charset.
95  // sjob->contentType()->setCharset( d->detectCharset( d->part->data() ) );
96 
97  // From my few tests, this is *very* unreliable.
98  // Therefore, if we do not know which charset to use, just use UTF-8.
99  // (cberzan)
100  QByteArray textCharset = d->part->charset();
101  if (textCharset.isEmpty()) {
102  qCWarning(MESSAGECOMPOSER_LOG) << "No charset specified. Using UTF-8.";
103  textCharset = "utf-8";
104  }
105  ct->setCharset(textCharset);
106  }
107 
108  sjob->contentDescription()->fromUnicodeString(d->part->description(), charset);
109 
110  auto contentDisposition = sjob->contentDisposition();
111  contentDisposition->setFilename(d->part->fileName());
112  contentDisposition->setRFC2047Charset(charset);
113  if (d->part->isInline()) {
114  contentDisposition->setDisposition(KMime::Headers::CDinline);
115  } else {
116  contentDisposition->setDisposition(KMime::Headers::CDattachment);
117  }
118 
119  ContentJobBase::doStart();
120 }
121 
122 void AttachmentJob::process()
123 {
124  Q_D(AttachmentJob);
125  // The content has been created by our subjob.
126  Q_ASSERT(d->subjobContents.count() == 1);
127  d->resultContent = d->subjobContents.constFirst();
128  emitResult();
129 }
bool isEmpty() const const
contentDisposition
The AttachmentJob class.
Definition: attachmentjob.h:21
KCharsets * charsets()
void setContent(const QByteArray &s)
Simple interface that both EncryptJob and SignEncryptJob implement so the composer can extract some e...
The SinglepartJob class.
Definition: singlepartjob.h:31
The ContentJobBase class.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Nov 26 2021 23:16:41 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.