File r890890.diff of Package kdepim4
Subject: kmail: various encoding fixes
From: wstephenson@suse.de
Bug: kde#64815
Patch-upstream: 890890
--- kmail/kmmsgbase.cpp (revision 890889)
+++ kmail/kmmsgbase.cpp (revision 890890)
@@ -400,17 +400,23 @@ QStringList KMMsgBase::supportedEncoding
}
//-----------------------------------------------------------------------------
-QString KMMsgBase::encodingForName( const QString &descriptiveName )
+QString KMMsgBase::fixEncoding( const QString &encoding )
{
- QString encoding = KGlobal::charsets()->encodingForName( descriptiveName );
-
+ QString returnEncoding = encoding;
// According to http://www.iana.org/assignments/character-sets, uppercase is
// prefered in MIME headers
- if ( encoding.toUpper().contains( "ISO " ) ) {
- encoding = encoding.toUpper();
- encoding.replace( "ISO ", "ISO-" );
+ if ( returnEncoding.toUpper().contains( "ISO " ) ) {
+ returnEncoding = returnEncoding.toUpper();
+ returnEncoding.replace( "ISO ", "ISO-" );
}
- return encoding;
+ return returnEncoding;
+}
+
+//-----------------------------------------------------------------------------
+QString KMMsgBase::encodingForName( const QString &descriptiveName )
+{
+ QString encoding = KGlobal::charsets()->encodingForName( descriptiveName );
+ return KMMsgBase::fixEncoding( encoding );
}
//-----------------------------------------------------------------------------
--- kmail/kmcomposewin.cpp (revision 890889)
+++ kmail/kmcomposewin.cpp (revision 890890)
@@ -83,7 +83,7 @@ using KPIM::DictionaryComboBox;
#include <kcursorsaver.h>
#include <kdebug.h>
#include <kedittoolbar.h>
-#include <kfiledialog.h>
+#include <kencodingfiledialog.h>
#include <kinputdialog.h>
#include <kmenu.h>
#include <kmimetypetrader.h>
@@ -2096,7 +2096,7 @@ bool KMComposeWin::addAttach( const KUrl
//-----------------------------------------------------------------------------
void KMComposeWin::addAttach( KMMessagePart *msgPart )
{
- mAtmList.append( (KMMessagePart*) msgPart );
+ mAtmList.append( msgPart );
// show the attachment listbox if it does not up to now
if ( mAtmList.count() == 1 ) {
@@ -2143,11 +2143,15 @@ QString KMComposeWin::prettyMimeType( co
const KMimeType::Ptr st = KMimeType::mimeType( t );
if ( !st ) {
- kWarning(5006) <<"unknown mimetype" << t;
- return QString();
+ kWarning() <<"unknown mimetype" << t;
+ return t;
}
- return !st->isDefault() ? st->comment() : t;
+ QString pretty = !st->isDefault() ? st->comment() : t;
+ if ( pretty.isEmpty() )
+ return type;
+ else
+ return pretty;
}
void KMComposeWin::msgPartToItem( const KMMessagePart *msgPart,
@@ -2272,8 +2276,8 @@ void KMComposeWin::slotAttachFile()
// We will not care about any permissions, existence or whatsoever in
// this function.
- KUrl url;
- KFileDialog fdlg( url, QString(), this );
+ KEncodingFileDialog fdlg( QString(), QString(), QString(), QString(),
+ KFileDialog::Opening, this );
fdlg.setOperationMode( KFileDialog::Other );
fdlg.setCaption( i18n("Attach File") );
fdlg.okButton()->setGuiItem( KGuiItem( i18n("&Attach"), "document-open") );
@@ -2282,8 +2286,11 @@ void KMComposeWin::slotAttachFile()
return;
const KUrl::List files = fdlg.selectedUrls();
- foreach ( const KUrl& url, files )
- addAttach( url );
+ foreach ( const KUrl& url, files ) {
+ KUrl urlWithEncoding = url;
+ urlWithEncoding.setFileEncoding( fdlg.selectedEncoding() );
+ addAttach( urlWithEncoding );
+ }
}
//-----------------------------------------------------------------------------
@@ -2344,19 +2351,36 @@ void KMComposeWin::slotAttachFileResult(
return;
}
+ // Determine the mime type of the attachment
+ QString mimeType = static_cast<KIO::TransferJob*>(job)->mimetype();
+ kDebug() << "Mimetype is" << mimeType;
+ int slash = mimeType.indexOf( '/' );
+ if( slash == -1 )
+ slash = mimeType.length();
+ QString type = mimeType.left( slash );
+ QString subType = mimeType.mid( slash + 1 );
+ bool isTextualType = ( type.toLower() == "text" );
+
+ //
+ // If the attachment is a textual mimetype, try to determine the charset.
+ //
QByteArray partCharset;
- if ( !loadData.url.fileEncoding().isEmpty() ) {
- partCharset = loadData.url.fileEncoding().toLatin1();
- } else {
- partCharset = mCharset;
+ if ( isTextualType ) {
+ if ( !loadData.url.fileEncoding().isEmpty() ) {
+ partCharset = KMMsgBase::fixEncoding( loadData.url.fileEncoding() ).toLatin1();
+ kDebug() << "Got charset from job:" << partCharset;
+ } else {
+ kWarning() << "No charset found, using UTF-8!";
+ partCharset = "utf-8";
+ }
}
- KMMessagePart* msgPart;
-
KCursorSaver busy( KBusyPtr::busy() );
+
+ //
+ // Try to determine the filename and the correct encoding for that filename.
+ //
QString name( loadData.url.fileName() );
- // ask the job for the mime type of the file
- QString mimeType = static_cast<KIO::TransferJob*>(job)->mimetype();
if ( name.isEmpty() ) {
// URL ends with '/' (e.g. http://www.kde.org/)
@@ -2375,30 +2399,35 @@ void KMComposeWin::slotAttachFileResult(
else if( i > 0 )
ext = ext.mid( i );
}
- name = QString("unknown") += ext;
+ name = QString( "unknown" ) + ext;
}
}
name.truncate( 256 ); // is this needed?
- QByteArray encoding = KMMsgBase::autoDetectCharset(partCharset,
- KMMessage::preferredCharsets(), name);
- if (encoding.isEmpty()) encoding = "utf-8";
+ // For the encoding of the name, prefer the current charset of the composer first,
+ // then try every other available encoding.
+ QByteArray nameEncoding =
+ KMMsgBase::autoDetectCharset( mCharset, KMMessage::preferredCharsets(), name );
+ if ( nameEncoding.isEmpty() )
+ nameEncoding = "utf-8";
- QByteArray encName;
+ QByteArray encodedName;
if ( GlobalSettings::self()->outlookCompatibleAttachments() ) {
- encName = KMMsgBase::encodeRFC2047String( name, encoding );
+ encodedName = KMMsgBase::encodeRFC2047String( name, nameEncoding );
} else {
- encName = KMMsgBase::encodeRFC2231String( name, encoding );
+ encodedName = KMMsgBase::encodeRFC2231String( name, nameEncoding );
}
bool RFC2231encoded = false;
if ( !GlobalSettings::self()->outlookCompatibleAttachments() ) {
- RFC2231encoded = name != QString( encName );
+ RFC2231encoded = name != QString( encodedName );
}
- // create message part
- msgPart = new KMMessagePart;
+ //
+ // Create message part
+ //
+ KMMessagePart *msgPart = new KMMessagePart;
msgPart->setName( name );
QList<int> allowedCTEs;
if ( mimeType == "message/rfc822" ) {
@@ -2408,21 +2437,20 @@ void KMComposeWin::slotAttachFileResult(
} else {
msgPart->setBodyAndGuessCte( loadData.data, allowedCTEs,
!kmkernel->msgSender()->sendQuotedPrintable() );
- kDebug(5006) <<"autodetected cte:" << msgPart->cteStr();
+ kDebug() << "Autodetected CTE:" << msgPart->cteStr();
}
- int slash = mimeType.indexOf( '/' );
- if( slash == -1 )
- slash = mimeType.length();
- msgPart->setTypeStr( mimeType.left( slash ).toLatin1() );
- msgPart->setSubtypeStr( mimeType.mid( slash + 1 ).toLatin1() );
- msgPart->setContentDisposition(QByteArray("attachment;\n\tfilename")
- + ( RFC2231encoded ? "*=" + encName : "=\"" + encName + '"' ) );
-
- mMapAtmLoadData.erase(it);
-
- msgPart->setCharset( partCharset );
-
- // show message part dialog, if not configured away (default):
+ msgPart->setTypeStr( type.toLatin1() );
+ msgPart->setSubtypeStr( subType.toLatin1() );
+ msgPart->setContentDisposition( QByteArray( "attachment;\n\tfilename" )
+ + ( RFC2231encoded ? "*=" + encodedName : "=\"" + encodedName + '"' ) );
+ if ( isTextualType )
+ msgPart->setCharset( partCharset );
+
+ mMapAtmLoadData.erase( it );
+
+ //
+ // Show message part dialog, if not configured away (default):
+ //
if ( GlobalSettings::self()->showMessagePartDialogOnAttach() ) {
const KCursorSaver saver( Qt::ArrowCursor );
KMMsgPartDialogCompat dlg;
@@ -2438,7 +2466,7 @@ void KMComposeWin::slotAttachFileResult(
}
dlg.setShownEncodings( encodings );
dlg.setMsgPart(msgPart);
- if (!dlg.exec()) {
+ if ( !dlg.exec() ) {
delete msgPart;
msgPart = 0;
if ( attachURLfound ) {
@@ -2447,9 +2475,9 @@ void KMComposeWin::slotAttachFileResult(
return;
}
}
+
+
mAtmModified = true;
- if ( msgPart->typeStr().toLower() != "text" )
- msgPart->setCharset( QByteArray() );
// add the new attachment to the list
addAttach( msgPart );
@@ -2462,29 +2490,27 @@ void KMComposeWin::slotAttachFileResult(
//-----------------------------------------------------------------------------
void KMComposeWin::slotInsertFile()
{
- QString encodingStr;
- KUrl u = mEditor->insertFile( KMMsgBase::supportedEncodings( false ),
- encodingStr );
+ KUrl u = mEditor->insertFile();
if ( u.isEmpty() )
return;
- mRecentAction->addUrl(u);
+ mRecentAction->addUrl( u );
// Prevent race condition updating list when multiple composers are open
{
KConfig *config = KMKernel::config();
KConfigGroup group( config, "Composer" );
- QString encoding = KMMsgBase::encodingForName( encodingStr ).toLatin1();
+ QString encoding = KMMsgBase::encodingForName( u.fileEncoding() ).toLatin1();
QStringList urls = group.readEntry( "recent-urls", QStringList() );
QStringList encodings = group.readEntry( "recent-encodings", QStringList() );
// Prevent config file from growing without bound
// Would be nicer to get this constant from KRecentFilesAction
- uint mMaxRecentFiles = 30;
- while ((uint)urls.count() > mMaxRecentFiles)
+ int mMaxRecentFiles = 30;
+ while ( urls.count() > mMaxRecentFiles )
urls.removeLast();
- while ((uint)encodings.count() > mMaxRecentFiles)
+ while ( encodings.count() > mMaxRecentFiles )
encodings.removeLast();
// sanity check
- if (urls.count() != encodings.count()) {
+ if ( urls.count() != encodings.count() ) {
urls.clear();
encodings.clear();
}
@@ -2494,7 +2520,7 @@ void KMComposeWin::slotInsertFile()
group.writeEntry( "recent-encodings", encodings );
mRecentAction->saveEntries( config->group( QString() ) );
}
- slotInsertRecentFile(u);
+ slotInsertRecentFile( u );
}
//-----------------------------------------------------------------------------
--- kmail/kmmsgbase.h (revision 890889)
+++ kmail/kmmsgbase.h (revision 890890)
@@ -256,8 +256,18 @@ public:
* where ascii, *ok will be set to false otherwise */
static QByteArray toUsAscii(const QString& _str, bool *ok=0);
- /** Return a list of the supported encodings */
- static QStringList supportedEncodings(bool usAscii);
+ /**
+ * Return a list of the supported encodings
+ * @param usAscii if true, US-Ascii encoding will be prepended to the list.
+ */
+ static QStringList supportedEncodings( bool usAscii );
+
+ /**
+ * Fixes an encoding received by a KDE function and returns the proper,
+ * MIME-compilant encoding name instead.
+ * @see encodingForName
+ */
+ static QString fixEncoding( const QString &encoding );
/**
* Drop-in replacement for KCharsets::encodingForName(). The problem with
--- libkdepim/kmeditor.cpp (revision 890889)
+++ libkdepim/kmeditor.cpp (revision 890890)
@@ -28,12 +28,11 @@
#include <kpimidentities/signature.h>
#include <kdeversion.h>
-#include <kabstractfilewidget.h>
#include <KCharsets>
#include <KComboBox>
#include <KCursor>
#include <KDirWatch>
-#include <KFileDialog>
+#include <KEncodingFileDialog>
#include <KLocale>
#include <KMenu>
#include <KMessageBox>
@@ -494,33 +493,18 @@ void KMeditor::setFontForWholeText( cons
document()->setDefaultFont( font );
}
-KUrl KMeditor::insertFile( const QStringList &encodingLst, QString &encodingStr )
+KUrl KMeditor::insertFile()
{
- KUrl url;
- KFileDialog fdlg( url, QString(), this );
- fdlg.setOperationMode( KFileDialog::Opening );
+ KEncodingFileDialog fdlg( QString(), QString(), QString(), QString(),
+ KFileDialog::Opening, this );
fdlg.okButton()->setText( i18n( "&Insert" ) );
fdlg.setCaption( i18n( "Insert File" ) );
-
- KComboBox *encodingCombo = 0;
- if ( !encodingLst.isEmpty() )
- {
- encodingCombo = new KComboBox( this );
- encodingCombo->addItems( encodingLst );
- // FIXME: after lifted string freeze: add back "Encoding" string
- fdlg.fileWidget()->setCustomWidget( /*i18n( "Encoding:" )*/QString(), encodingCombo );
- for ( int i = 0; i < encodingCombo->count(); i++ )
- if ( KGlobal::charsets()->codecForName( KGlobal::charsets()->
- encodingForName( encodingCombo->itemText( i ) ) )
- == QTextCodec::codecForLocale() )
- encodingCombo->setCurrentIndex(i);
- }
if ( !fdlg.exec() )
return KUrl();
else {
- if ( encodingCombo )
- encodingStr = encodingCombo->currentText();
- return fdlg.selectedUrl();
+ KUrl url = fdlg.selectedUrl();
+ url.setFileEncoding( fdlg.selectedEncoding() );
+ return url;
}
}
--- libkdepim/kmeditor.h (revision 890889)
+++ libkdepim/kmeditor.h (revision 890890)
@@ -92,7 +92,12 @@ class KDEPIM_EXPORT KMeditor : public KR
/// FIXME: Huh? This is not virtual in the base classes and thus never called
void paste();
- KUrl insertFile( const QStringList &encodingLst, QString &encodingStr );
+ /**
+ * Show the open file dialog and returns the selected URL there.
+ * The file dialog has an encoding combobox displayed, and the selected
+ * encoding there will be set as the encoding of the URL's fileEncoding().
+ */
+ KUrl insertFile();
/**
* Enables word wrap. Words will be wrapped at the specified column.
Index: kmail/kmmsgbase.cpp
===================================================================
Index: kmail/kmcomposewin.cpp
===================================================================
Index: kmail/kmmsgbase.h
===================================================================
Index: libkdepim/kmeditor.cpp
===================================================================
Index: libkdepim/kmeditor.h
===================================================================