Backport r952870 | aacid | 2009-04-12 20:31:54 +0200 (Sun, 12 Apr 2009) | 3 lines
[kdepim.git] / kmail / kmmsgpartdlg.cpp
blob43bb8ad48d815479e5e7efa12049ec681e3d4f1f
1 // kmmsgpartdlg.cpp
4 // my includes:
5 #include "kmmsgpartdlg.h"
7 // other KMail includes:
8 #include "kmmessage.h"
9 #include "kmmsgpart.h"
10 #include "kcursorsaver.h"
12 // other kdenetwork includes: (none)
14 // other KDE includes:
15 #include <klineedit.h>
16 #include <kmimetype.h>
17 #include <kiconloader.h>
18 #include <kaboutdata.h>
19 #include <kstringvalidator.h>
20 #include <kcombobox.h>
21 #include <kdebug.h>
22 #include <klocale.h>
23 #include <kcomponentdata.h>
25 // other Qt includes:
26 #include <QLabel>
27 #include <QLayout>
29 //Added by qt3to4:
30 #include <QGridLayout>
31 #include <QByteArray>
32 #include <QCheckBox>
34 // other includes:
35 #include <assert.h>
37 static const struct {
38 KMMsgPartDialog::Encoding encoding;
39 const char * displayName;
40 } encodingTypes[] = {
41 { KMMsgPartDialog::SevenBit, I18N_NOOP2("message encoding type", "None (7-bit text)") },
42 { KMMsgPartDialog::EightBit, I18N_NOOP2("message encoding type", "None (8-bit text)") },
43 { KMMsgPartDialog::QuotedPrintable, I18N_NOOP2("message encoding type", "Quoted Printable") },
44 { KMMsgPartDialog::Base64, I18N_NOOP2("message encoding type", "Base 64") },
46 static const int numEncodingTypes =
47 sizeof encodingTypes / sizeof *encodingTypes;
49 KMMsgPartDialog::KMMsgPartDialog( const QString & caption,
50 QWidget * parent )
51 : KDialog( parent )
53 setCaption( caption.isEmpty() ? i18n("Message Part Properties") : caption );
54 setButtons( Ok|Cancel|Help );
55 setDefaultButton( Ok );
56 setModal( true );
57 showButtonSeparator( true );
59 // tmp vars:
60 QGridLayout * glay;
61 QLabel * label;
62 QString msg;
64 setHelp( QString::fromLatin1("attachments") );
66 for ( int i = 0 ; i < numEncodingTypes ; ++i )
67 mI18nizedEncodings << i18nc( "message encoding type", encodingTypes[i].displayName );
68 QFrame *frame = new QFrame( this );
69 setMainWidget( frame );
70 glay = new QGridLayout(frame );
71 glay->setSpacing( spacingHint() );
72 glay->setColumnStretch( 1, 1 );
73 glay->setRowStretch( 8, 1 );
75 // mimetype icon:
76 mIcon = new QLabel( frame );
77 mIcon->setPixmap( DesktopIcon("unknown") );
78 glay->addWidget( mIcon, 0, 0, 2, 1);
80 // row 0: Type combobox:
81 mMimeType = new KComboBox( true, frame );
82 mMimeType->setInsertPolicy( KComboBox::NoInsert );
83 mMimeType->setValidator( new KMimeTypeValidator( mMimeType ) );
84 mMimeType->addItems( QStringList()
85 << QString::fromLatin1("text/html")
86 << QString::fromLatin1("text/plain")
87 << QString::fromLatin1("image/gif")
88 << QString::fromLatin1("image/jpeg")
89 << QString::fromLatin1("image/png")
90 << QString::fromLatin1("application/octet-stream")
91 << QString::fromLatin1("application/x-gunzip")
92 << QString::fromLatin1("application/zip") );
93 connect( mMimeType, SIGNAL(editTextChanged(const QString&)),
94 this, SLOT(slotMimeTypeChanged(const QString&)) );
95 glay->addWidget( mMimeType, 0, 1 );
97 msg = i18n("<qt><p>The <em>MIME type</em> of the file:</p>"
98 "<p>normally, you do not need to touch this setting, since the "
99 "type of the file is automatically checked; but, sometimes, %1 "
100 "may not detect the type correctly -- here is where you can fix "
101 "that.</p></qt>", KGlobal::mainComponent().aboutData()->programName() );
102 mMimeType->setWhatsThis( msg );
104 // row 1: Size label:
105 mSize = new QLabel( frame );
106 setSize( KIO::filesize_t(0) );
107 glay->addWidget( mSize, 1, 1 );
109 msg = i18n("<qt><p>The size of the part:</p>"
110 "<p>sometimes, %1 will only give an estimated size here, "
111 "because calculating the exact size would take too much time; "
112 "when this is the case, it will be made visible by adding "
113 "\"(est.)\" to the size displayed.</p></qt>",
114 KGlobal::mainComponent().aboutData()->programName() );
115 mSize->setWhatsThis( msg );
117 // row 2: "Name" lineedit and label:
118 mFileName = new KLineEdit( frame );
119 mFileName->setClearButtonShown( true );
120 label = new QLabel( i18nc("file name of the attachment.", "&Name:"), frame );
121 label->setBuddy( mFileName );
122 glay->addWidget( label, 2, 0 );
123 glay->addWidget( mFileName, 2, 1 );
125 msg = i18n("<qt><p>The file name of the part:</p>"
126 "<p>although this defaults to the name of the attached file, "
127 "it does not specify the file to be attached; rather, it "
128 "suggests a file name to be used by the recipient's mail agent "
129 "when saving the part to disk.</p></qt>");
130 label->setWhatsThis( msg );
131 mFileName->setWhatsThis( msg );
133 // row 3: "Description" lineedit and label:
134 mDescription = new KLineEdit( frame );
135 mDescription->setClearButtonShown( true );
136 label = new QLabel( i18n("&Description:"), frame );
137 label->setBuddy( mDescription );
138 glay->addWidget( label, 3, 0 );
139 glay->addWidget( mDescription, 3, 1 );
141 msg = i18n("<qt><p>A description of the part:</p>"
142 "<p>this is just an informational description of the part, "
143 "much like the Subject is for the whole message; most "
144 "mail agents will show this information in their message "
145 "previews alongside the attachment's icon.</p></qt>");
146 label->setWhatsThis( msg );
147 mDescription->setWhatsThis( msg );
149 // row 4: "Encoding" combobox and label:
150 mEncoding = new KComboBox( frame );
151 mEncoding->setEditable( false );
152 mEncoding->addItems( mI18nizedEncodings );
153 label = new QLabel( i18n("&Encoding:"), frame );
154 label->setBuddy( mEncoding );
155 glay->addWidget( label, 4, 0 );
156 glay->addWidget( mEncoding, 4, 1 );
158 msg = i18n("<qt><p>The transport encoding of this part:</p>"
159 "<p>normally, you do not need to change this, since %1 will use "
160 "a decent default encoding, depending on the MIME type; yet, "
161 "sometimes, you can significantly reduce the size of the "
162 "resulting message, e.g. if a PostScript file does not contain "
163 "binary data, but consists of pure text -- in this case, choosing "
164 "\"quoted-printable\" over the default \"base64\" will save up "
165 "to 25% in resulting message size.</p></qt>",
166 KGlobal::mainComponent().aboutData()->programName() );
167 label->setWhatsThis( msg );
168 mEncoding->setWhatsThis( msg );
170 // row 5: "Suggest automatic display..." checkbox:
171 mInline = new QCheckBox( i18n("Suggest &automatic display"), frame );
172 glay->addWidget( mInline, 5, 0, 1, 2 );
174 msg = i18n("<qt><p>Check this option if you want to suggest to the "
175 "recipient the automatic (inline) display of this part in the "
176 "message preview, instead of the default icon view;</p>"
177 "<p>technically, this is carried out by setting this part's "
178 "<em>Content-Disposition</em> header field to \"inline\" "
179 "instead of the default \"attachment\".</p></qt>");
180 mInline->setWhatsThis( msg );
182 // row 6: "Sign" checkbox:
183 mSigned = new QCheckBox( i18n("&Sign this part"), frame );
184 glay->addWidget( mSigned, 6, 0, 1, 2 );
186 msg = i18n("<qt><p>Check this option if you want this message part to be "
187 "signed;</p>"
188 "<p>the signature will be made with the key that you associated "
189 "with the currently-selected identity.</p></qt>");
190 mSigned->setWhatsThis( msg );
192 // row 7: "Encrypt" checkbox:
193 mEncrypted = new QCheckBox( i18n("Encr&ypt this part"), frame );
194 glay->addWidget( mEncrypted, 7, 0, 1, 2 );
196 msg = i18n("<qt><p>Check this option if you want this message part to be "
197 "encrypted;</p>"
198 "<p>the part will be encrypted for the recipients of this "
199 "message</p></qt>");
200 mEncrypted->setWhatsThis( msg );
201 // (row 8: spacer)
205 KMMsgPartDialog::~KMMsgPartDialog() {}
208 QString KMMsgPartDialog::mimeType() const {
209 return mMimeType->currentText();
212 void KMMsgPartDialog::setMimeType( const QString & mimeType ) {
213 for ( int i = 0 ; i < mMimeType->count() ; ++i )
214 if ( mMimeType->itemText( i ) == mimeType ) {
215 mMimeType->setCurrentIndex( i );
216 slotMimeTypeChanged( mimeType );
217 return;
219 mMimeType->insertItem( 0, mimeType );
220 mMimeType->setCurrentIndex( 0 );
221 slotMimeTypeChanged( mimeType );
224 void KMMsgPartDialog::setMimeType( const QString & type,
225 const QString & subtype ) {
226 setMimeType( QString::fromLatin1("%1/%2").arg(type).arg(subtype) );
229 void KMMsgPartDialog::setMimeTypeList( const QStringList & mimeTypes ) {
230 mMimeType->addItems( mimeTypes );
233 void KMMsgPartDialog::setSize( KIO::filesize_t size, bool estimated ) {
234 QString text = KIO::convertSize( size );
235 if ( estimated )
236 text = i18nc("%1: a filesize incl. unit (e.g. \"1.3 KB\")",
237 "%1 (est.)", text );
238 mSize->setText( text );
241 QString KMMsgPartDialog::fileName() const {
242 return mFileName->text();
245 void KMMsgPartDialog::setFileName( const QString & fileName ) {
246 mFileName->setText( fileName );
249 QString KMMsgPartDialog::description() const {
250 return mDescription->text();
253 void KMMsgPartDialog::setDescription( const QString & description ) {
254 mDescription->setText( description );
257 KMMsgPartDialog::Encoding KMMsgPartDialog::encoding() const {
258 QString s = mEncoding->currentText();
259 for ( int i = 0 ; i < mI18nizedEncodings.count() ; ++i )
260 if ( s == mI18nizedEncodings.at(i) )
261 return encodingTypes[i].encoding;
262 kFatal(5006) <<"KMMsgPartDialog::encoding(): Unknown encoding encountered!";
263 return None; // keep compiler happy
266 void KMMsgPartDialog::setEncoding( Encoding encoding ) {
267 for ( int i = 0 ; i < numEncodingTypes ; ++i )
268 if ( encodingTypes[i].encoding == encoding ) {
269 QString text = mI18nizedEncodings.at(i);
270 for ( int j = 0 ; j < mEncoding->count() ; ++j )
271 if ( mEncoding->itemText(j) == text ) {
272 mEncoding->setCurrentIndex( j );
273 return;
275 mEncoding->insertItem( 0, text );
276 mEncoding->setCurrentIndex( 0 );
278 kFatal(5006) <<"KMMsgPartDialog::setEncoding():"
279 "Unknown encoding encountered!";
282 void KMMsgPartDialog::setShownEncodings( int encodings ) {
283 mEncoding->clear();
284 for ( int i = 0 ; i < numEncodingTypes ; ++i )
285 if ( encodingTypes[i].encoding & encodings )
286 mEncoding->addItem( mI18nizedEncodings.at(i) );
289 bool KMMsgPartDialog::isInline() const {
290 return mInline->isChecked();
293 void KMMsgPartDialog::setInline( bool inlined ) {
294 mInline->setChecked( inlined );
297 bool KMMsgPartDialog::isEncrypted() const {
298 return mEncrypted->isChecked();
301 void KMMsgPartDialog::setEncrypted( bool encrypted ) {
302 mEncrypted->setChecked( encrypted );
305 void KMMsgPartDialog::setCanEncrypt( bool enable ) {
306 mEncrypted->setEnabled( enable );
309 bool KMMsgPartDialog::isSigned() const {
310 return mSigned->isChecked();
313 void KMMsgPartDialog::setSigned( bool sign ) {
314 mSigned->setChecked( sign );
317 void KMMsgPartDialog::setCanSign( bool enable ) {
318 mSigned->setEnabled( enable );
321 void KMMsgPartDialog::slotMimeTypeChanged( const QString & mimeType ) {
322 // message subparts MUST have 7bit or 8bit encoding...
323 #if 0
324 // ...but until KMail can recode 8bit messages on attach, so that
325 // they can be signed, we can't enforce this :-(
326 if ( mimeType.startsWith("message/") ) {
327 setEncoding( SevenBit );
328 mEncoding->setEnabled( false );
329 } else {
330 mEncoding->setEnabled( !mReadOnly );
332 #endif
333 // find a mimetype icon:
334 KMimeType::Ptr mt = KMimeType::mimeType( mimeType, KMimeType::ResolveAliases );
335 if ( !mt.isNull() )
336 mIcon->setPixmap( KIconLoader::global()->loadMimeTypeIcon( mt->iconName(),
337 KIconLoader::Desktop ) );
338 else
339 mIcon->setPixmap( DesktopIcon("unknown") );
345 KMMsgPartDialogCompat::KMMsgPartDialogCompat( const char *, bool readOnly)
346 : KMMsgPartDialog(), mMsgPart( 0 )
348 setShownEncodings( SevenBit|EightBit|QuotedPrintable|Base64 );
349 if (readOnly)
351 mMimeType->setEditable(false);
352 mMimeType->setEnabled(false);
353 mFileName->setReadOnly(true);
354 mDescription->setReadOnly(true);
355 mEncoding->setEnabled(false);
356 mInline->setEnabled(false);
357 mEncrypted->setEnabled(false);
358 mSigned->setEnabled(false);
360 connect(this,SIGNAL(okClicked()),SLOT(slotOk()));
363 KMMsgPartDialogCompat::~KMMsgPartDialogCompat() {}
365 void KMMsgPartDialogCompat::setMsgPart( KMMessagePart * aMsgPart )
367 mMsgPart = aMsgPart;
368 assert( mMsgPart );
370 QByteArray enc = mMsgPart->cteStr();
371 if ( enc == "7bit" )
372 setEncoding( SevenBit );
373 else if ( enc == "8bit" )
374 setEncoding( EightBit );
375 else if ( enc == "quoted-printable" )
376 setEncoding( QuotedPrintable );
377 else
378 setEncoding( Base64 );
380 setDescription( mMsgPart->contentDescription() );
381 setFileName( mMsgPart->fileName() );
382 setMimeType( mMsgPart->typeStr(), mMsgPart->subtypeStr() );
383 setSize( mMsgPart->decodedSize() );
384 QString cd(mMsgPart->contentDisposition());
385 setInline( cd.indexOf( QRegExp("^\\s*inline", Qt::CaseInsensitive) ) >= 0 );
389 void KMMsgPartDialogCompat::applyChanges()
391 if (!mMsgPart) return;
393 KCursorSaver busy(KBusyPtr::busy());
395 // apply Content-Disposition:
396 QByteArray cDisp;
397 if ( isInline() )
398 cDisp = "inline;";
399 else
400 cDisp = "attachment;";
402 QString name = fileName();
403 if ( !name.isEmpty() || !mMsgPart->name().isEmpty()) {
404 mMsgPart->setName( name );
405 QByteArray encoding = KMMsgBase::autoDetectCharset( mMsgPart->charset(),
406 KMMessage::preferredCharsets(), name );
407 if ( encoding.isEmpty() ) encoding = "utf-8";
408 QByteArray encName = KMMsgBase::encodeRFC2231String( name, encoding );
410 cDisp += "\n\tfilename";
411 if ( name != QString( encName ) )
412 cDisp += "*=" + encName;
413 else
414 cDisp += "=\"" + encName.replace( '\\', "\\\\" ).replace( '"', "\\\"" ) + '"';
415 mMsgPart->setContentDisposition( cDisp );
418 // apply Content-Description"
419 QString desc = description();
420 if ( !desc.isEmpty() || !mMsgPart->contentDescription().isEmpty() )
421 mMsgPart->setContentDescription( desc );
423 // apply Content-Type:
424 QByteArray type = mimeType().toLatin1();
425 QByteArray subtype;
426 int idx = type.indexOf('/');
427 if ( idx < 0 )
428 subtype = "";
429 else {
430 subtype = type.mid( idx+1 );
431 type = type.left( idx );
433 mMsgPart->setTypeStr(type);
434 mMsgPart->setSubtypeStr(subtype);
436 // apply Content-Transfer-Encoding:
437 QByteArray cte;
438 if (subtype == "rfc822" && type == "message")
439 kWarning( encoding() != SevenBit && encoding() != EightBit, 5006 )
440 << "encoding on rfc822/message must be \"7bit\" or \"8bit\"";
441 switch ( encoding() ) {
442 case SevenBit: cte = "7bit"; break;
443 case EightBit: cte = "8bit"; break;
444 case QuotedPrintable: cte = "quoted-printable"; break;
445 case Base64: default: cte = "base64"; break;
447 if ( cte != mMsgPart->cteStr().toLower() ) {
448 QByteArray body = mMsgPart->bodyDecodedBinary();
449 mMsgPart->setCteStr( cte );
450 mMsgPart->setBodyEncodedBinary( body );
455 //-----------------------------------------------------------------------------
456 void KMMsgPartDialogCompat::slotOk()
458 applyChanges();
462 //-----------------------------------------------------------------------------
463 #include "kmmsgpartdlg.moc"