5 #include "kmmsgpartdlg.h"
7 // other KMail includes:
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>
23 #include <kcomponentdata.h>
30 #include <QGridLayout>
38 KMMsgPartDialog::Encoding encoding
;
39 const char * displayName
;
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
,
53 setCaption( caption
.isEmpty() ? i18n("Message Part Properties") : caption
);
54 setButtons( Ok
|Cancel
|Help
);
55 setDefaultButton( Ok
);
57 showButtonSeparator( true );
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 );
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 "
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 "
198 "<p>the part will be encrypted for the recipients of this "
200 mEncrypted
->setWhatsThis( msg
);
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
);
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
);
236 text
= i18nc("%1: a filesize incl. unit (e.g. \"1.3 KB\")",
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
);
275 mEncoding
->insertItem( 0, text
);
276 mEncoding
->setCurrentIndex( 0 );
278 kFatal(5006) <<"KMMsgPartDialog::setEncoding():"
279 "Unknown encoding encountered!";
282 void KMMsgPartDialog::setShownEncodings( int encodings
) {
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...
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 );
330 mEncoding
->setEnabled( !mReadOnly
);
333 // find a mimetype icon:
334 KMimeType::Ptr mt
= KMimeType::mimeType( mimeType
, KMimeType::ResolveAliases
);
336 mIcon
->setPixmap( KIconLoader::global()->loadMimeTypeIcon( mt
->iconName(),
337 KIconLoader::Desktop
) );
339 mIcon
->setPixmap( DesktopIcon("unknown") );
345 KMMsgPartDialogCompat::KMMsgPartDialogCompat( const char *, bool readOnly
)
346 : KMMsgPartDialog(), mMsgPart( 0 )
348 setShownEncodings( SevenBit
|EightBit
|QuotedPrintable
|Base64
);
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
)
370 QByteArray enc
= mMsgPart
->cteStr();
372 setEncoding( SevenBit
);
373 else if ( enc
== "8bit" )
374 setEncoding( EightBit
);
375 else if ( enc
== "quoted-printable" )
376 setEncoding( QuotedPrintable
);
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:
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
;
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();
426 int idx
= type
.indexOf('/');
430 subtype
= type
.mid( idx
+1 );
431 type
= type
.left( idx
);
433 mMsgPart
->setTypeStr(type
);
434 mMsgPart
->setSubtypeStr(subtype
);
436 // apply Content-Transfer-Encoding:
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()
462 //-----------------------------------------------------------------------------
463 #include "kmmsgpartdlg.moc"