File indexing completed on 2024-06-23 05:18:33
0001 /* 0002 SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "job/singlepartjob.h" 0008 0009 #include "contentjobbase_p.h" 0010 #include "part/globalpart.h" 0011 0012 #include "messagecomposer_debug.h" 0013 #include <KLocalizedString> 0014 0015 #include <KMime/Content> 0016 #include <KMime/Headers> 0017 0018 using namespace MessageComposer; 0019 0020 class MessageComposer::SinglepartJobPrivate : public ContentJobBasePrivate 0021 { 0022 public: 0023 SinglepartJobPrivate(SinglepartJob *qq) 0024 : ContentJobBasePrivate(qq) 0025 { 0026 } 0027 0028 bool chooseCTE(); 0029 0030 QByteArray data; 0031 KMime::Headers::ContentDescription *contentDescription = nullptr; 0032 KMime::Headers::ContentDisposition *contentDisposition = nullptr; 0033 KMime::Headers::ContentID *contentID = nullptr; 0034 KMime::Headers::ContentTransferEncoding *contentTransferEncoding = nullptr; 0035 KMime::Headers::ContentType *contentType = nullptr; 0036 0037 Q_DECLARE_PUBLIC(SinglepartJob) 0038 }; 0039 0040 bool SinglepartJobPrivate::chooseCTE() 0041 { 0042 Q_Q(SinglepartJob); 0043 0044 auto allowed = KMime::encodingsForData(data); 0045 0046 if (!q->globalPart()->is8BitAllowed()) { 0047 allowed.removeAll(KMime::Headers::CE8Bit); 0048 } 0049 0050 #if 0 // TODO signing 0051 // In the following cases only QP and Base64 are allowed: 0052 // - the buffer will be OpenPGP/MIME signed and it contains trailing 0053 // whitespace (cf. RFC 3156) 0054 // - a line starts with "From " 0055 if ((willBeSigned && cf.hasTrailingWhitespace()) 0056 || cf.hasLeadingFrom()) { 0057 ret.removeAll(DwMime::kCte8bit); 0058 ret.removeAll(DwMime::kCte7bit); 0059 } 0060 #endif 0061 0062 if (contentTransferEncoding) { 0063 // Specific CTE set. Check that our data fits in it. 0064 if (!allowed.contains(contentTransferEncoding->encoding())) { 0065 q->setError(JobBase::BugError); 0066 q->setErrorText( 0067 i18n("%1 Content-Transfer-Encoding cannot correctly encode this message.", KMime::nameForEncoding(contentTransferEncoding->encoding()))); 0068 return false; 0069 // TODO improve error message in case 8bit is requested but not allowed. 0070 } 0071 } else { 0072 // No specific CTE set. Choose the best one. 0073 Q_ASSERT(!allowed.isEmpty()); 0074 contentTransferEncoding = new KMime::Headers::ContentTransferEncoding; 0075 contentTransferEncoding->setEncoding(allowed.first()); 0076 } 0077 qCDebug(MESSAGECOMPOSER_LOG) << "Settled on encoding" << KMime::nameForEncoding(contentTransferEncoding->encoding()); 0078 return true; 0079 } 0080 0081 SinglepartJob::SinglepartJob(QObject *parent) 0082 : ContentJobBase(*new SinglepartJobPrivate(this), parent) 0083 { 0084 } 0085 0086 SinglepartJob::~SinglepartJob() = default; 0087 0088 QByteArray SinglepartJob::data() const 0089 { 0090 Q_D(const SinglepartJob); 0091 return d->data; 0092 } 0093 0094 void SinglepartJob::setData(const QByteArray &data) 0095 { 0096 Q_D(SinglepartJob); 0097 d->data = data; 0098 } 0099 0100 KMime::Headers::ContentDescription *SinglepartJob::contentDescription() 0101 { 0102 Q_D(SinglepartJob); 0103 if (!d->contentDescription) { 0104 d->contentDescription = new KMime::Headers::ContentDescription; 0105 } 0106 return d->contentDescription; 0107 } 0108 0109 KMime::Headers::ContentDisposition *SinglepartJob::contentDisposition() 0110 { 0111 Q_D(SinglepartJob); 0112 if (!d->contentDisposition) { 0113 d->contentDisposition = new KMime::Headers::ContentDisposition; 0114 } 0115 return d->contentDisposition; 0116 } 0117 0118 KMime::Headers::ContentID *SinglepartJob::contentID() 0119 { 0120 Q_D(SinglepartJob); 0121 if (!d->contentID) { 0122 d->contentID = new KMime::Headers::ContentID; 0123 } 0124 return d->contentID; 0125 } 0126 0127 KMime::Headers::ContentTransferEncoding *SinglepartJob::contentTransferEncoding() 0128 { 0129 Q_D(SinglepartJob); 0130 if (!d->contentTransferEncoding) { 0131 d->contentTransferEncoding = new KMime::Headers::ContentTransferEncoding; 0132 } 0133 return d->contentTransferEncoding; 0134 } 0135 0136 KMime::Headers::ContentType *SinglepartJob::contentType() 0137 { 0138 Q_D(SinglepartJob); 0139 if (!d->contentType) { 0140 d->contentType = new KMime::Headers::ContentType; 0141 } 0142 return d->contentType; 0143 } 0144 0145 void SinglepartJob::process() 0146 { 0147 Q_D(SinglepartJob); 0148 Q_ASSERT(d->resultContent == nullptr); // Not processed before. 0149 d->resultContent = new KMime::Content; 0150 0151 if (!d->chooseCTE()) { 0152 Q_ASSERT(error()); 0153 emitResult(); 0154 return; 0155 } 0156 0157 // Set headers. 0158 if (d->contentDescription) { 0159 d->resultContent->setHeader(d->contentDescription); 0160 } 0161 if (d->contentDisposition) { 0162 d->resultContent->setHeader(d->contentDisposition); 0163 } 0164 if (d->contentID) { 0165 d->resultContent->setHeader(d->contentID); 0166 } 0167 Q_ASSERT(d->contentTransferEncoding); // chooseCTE() created it if it didn't exist. 0168 { 0169 d->resultContent->setHeader(d->contentTransferEncoding); 0170 } 0171 if (d->contentType) { 0172 d->resultContent->setHeader(d->contentType); 0173 } 0174 0175 // Set data. 0176 d->resultContent->setBody(d->data); 0177 0178 emitResult(); 0179 } 0180 0181 #include "moc_singlepartjob.cpp"