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
===================================================================
openSUSE Build Service is sponsored by