2 Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
4 Parts based on KMail code by:
7 This library is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Library General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 This library is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 License for more details.
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "attachmentjob.h"
25 #include <boost/shared_ptr.hpp>
27 #include <KEncodingProber>
29 #include "contentjobbase_p.h"
30 #include "globalpart.h"
31 #include "singlepartjob.h"
36 using namespace Message
;
39 class Message::AttachmentJobPrivate
: public ContentJobBasePrivate
42 AttachmentJobPrivate( AttachmentJob
*qq
)
43 : ContentJobBasePrivate( qq
)
47 //QByteArray detectCharset( const QByteArray &data );
49 AttachmentPart::Ptr part
;
51 Q_DECLARE_PUBLIC( AttachmentJob
)
55 QByteArray
AttachmentJobPrivate::detectCharset( const QByteArray
&data
)
57 KEncodingProber prober
;
59 kDebug() << "Autodetected charset" << prober
.encoding() << "with confidence" << prober
.confidence();
61 // The prober detects binary attachments as UTF-16LE with confidence 99%, which
62 // obviously is wrong, so work around this here (most mail clients don't understand
64 const QByteArray detectedEncoding
= prober
.encoding();
65 if( prober
.confidence() > 0.6 && !detectedEncoding
.toLower().contains( "utf-16" ) ) {
66 return detectedEncoding
;
68 kWarning() << "Could not autodetect charset; using UTF-8.";
69 return QByteArray( "utf-8" );
76 AttachmentJob::AttachmentJob( AttachmentPart::Ptr part
, QObject
*parent
)
77 : ContentJobBase( *new AttachmentJobPrivate( this ), parent
)
83 AttachmentJob::~AttachmentJob()
87 AttachmentPart::Ptr
AttachmentJob::attachmentPart() const
89 Q_D( const AttachmentJob
);
93 void AttachmentJob::setAttachmentPart( AttachmentPart::Ptr part
)
99 void AttachmentJob::doStart()
101 Q_D( AttachmentJob
);
104 if( d
->part
->mimeType() == "multipart/digest" ||
105 d
->part
->mimeType() == "message/rfc822" ) {
106 // this is actually a digest, so we don't want any additional headers
107 // the attachment is really a complete multipart/digest subtype
108 // and us adding our own headers would break it. so copy over the content
109 // and leave it alone
110 KMime::Content
* part
= new KMime::Content
;
111 part
->setContent( d
->part
->data() );
113 d
->subjobContents
<< part
;
118 // Set up a subjob to generate the attachment content.
119 SinglepartJob
*sjob
= new SinglepartJob( this );
120 sjob
->setData( d
->part
->data() );
122 // Figure out a charset to encode parts of the headers with.
123 const QString dataToEncode
= d
->part
->name() + d
->part
->description() + d
->part
->fileName();
124 const QByteArray charset
= Util::selectCharset( globalPart()->charsets( true ), dataToEncode
);
126 // Set up the headers.
127 // rfc822 forwarded messages have 7bit CTE, the message itself will have
128 // its own CTE for the content
129 if( d
->part
->mimeType() == "message/rfc822" )
130 sjob
->contentTransferEncoding()->setEncoding( KMime::Headers::CE7Bit
);
132 sjob
->contentTransferEncoding()->setEncoding( d
->part
->encoding() );
134 sjob
->contentType()->setMimeType( d
->part
->mimeType() ); // setMimeType() clears all other params.
135 sjob
->contentType()->setName( d
->part
->name(), charset
);
136 if( sjob
->contentType()->isText() ) {
137 // If it is a text file, detect its charset.
138 //sjob->contentType()->setCharset( d->detectCharset( d->part->data() ) );
140 // From my few tests, this is *very* unreliable.
141 // Therefore, if we do not know which charset to use, just use UTF-8.
143 QByteArray textCharset
= d
->part
->charset();
144 if( textCharset
.isEmpty() ) {
145 kWarning() << "No charset specified. Using UTF-8.";
146 textCharset
= "utf-8";
148 sjob
->contentType()->setCharset( textCharset
);
151 sjob
->contentDescription()->fromUnicodeString( d
->part
->description(), charset
);
153 sjob
->contentDisposition()->setFilename( d
->part
->fileName() );
154 sjob
->contentDisposition()->setRFC2047Charset( charset
);
155 if( d
->part
->isInline() ) {
156 sjob
->contentDisposition()->setDisposition( KMime::Headers::CDinline
);
158 sjob
->contentDisposition()->setDisposition( KMime::Headers::CDattachment
);
161 ContentJobBase::doStart();
164 void AttachmentJob::process()
166 Q_D( AttachmentJob
);
167 // The content has been created by our subjob.
168 Q_ASSERT( d
->subjobContents
.count() == 1 );
169 d
->resultContent
= d
->subjobContents
.first();
173 #include "attachmentjob.moc"