Bug 94724 - Integrate ktnef into kmail
Summary: Integrate ktnef into kmail
Status: RESOLVED FIXED
Alias: None
Product: kmail
Classification: Applications
Component: general (show other bugs)
Version: 1.6.2
Platform: unspecified Linux
: NOR wishlist
Target Milestone: ---
Assignee: kdepim bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-12-09 08:05 UTC by xsov
Modified: 2007-09-14 12:17 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description xsov 2004-12-09 08:05:26 UTC
Version:           1.6.2 (using KDE 3.2.3, compiled sources)
Compiler:          gcc version 3.3.3
OS:                Linux (i686) release 2.4.27

Why not integrate ktnef functionality directly into Kmail? So files from TNEF-archive will be shown just like usual attachments when viewing e-mail with its internal icons (supplied with TNEF-archive)?

It is not handily using external application, such as ktnef.

It may be released as library libtnef, which will be used by kmail and ktnef :)

Or there is some patent/license restrictions?
Comment 1 Konrad Dear 2005-05-02 14:18:40 UTC
I agree,  I think this would be good idea to do.  This is even more relevant when you start sharing Kmail with Outlook against the same email account.  Outlook and Exchange tend to conspire together and add to every message you open a tnef attachment, even those messages without prior attachments.  Perhaps it's their way of updating message flags?

It's particularly annoying seeing every message with a tnef attachment.

I also have thousands of emails, prior to discovering Linux :), with tnefs embedded into them.

To be able to skip the step of saving / opening tnef files would be great.
Comment 2 Jan de Visser 2005-05-02 14:30:46 UTC
I was thinking about/working on this a while ago (sept 2004), but got distracted (work :(. I will see if I can ever pick it up again.
Comment 3 Volker Krause 2007-04-03 23:01:00 UTC
SVN commit 650109 by vkrause:

Merge inline-viewing of TNEF attachments from the KDE PIM enterprise
branch.

FEATURE: 94724

Approved by Ingo and Allen.


 M  +1 -0      Makefile.am  
 M  +4 -2      bodypartformatter.cpp  
 M  +21 -14    kmreaderwin.cpp  
 M  +8 -1      kmreaderwin.h  
 M  +73 -0     objecttreeparser.cpp  
 M  +2 -1      objecttreeparser.h  


--- branches/KDE/3.5/kdepim/kmail/Makefile.am #650108:650109
@@ -14,6 +14,7 @@
 	-I$(top_srcdir)/certmanager/lib \
         -I$(top_srcdir)/certmanager/lib/ui \
         -I$(top_srcdir)/indexlib \
+        -I$(top_srcdir)/ktnef \
         -I$(top_srcdir) \
         $(GPGME_CFLAGS) \
         $(all_includes)
--- branches/KDE/3.5/kdepim/kmail/bodypartformatter.cpp #650108:650109
@@ -114,6 +114,7 @@
   CREATE_BODY_PART_FORMATTER(ApplicationPkcs7Mime)
   CREATE_BODY_PART_FORMATTER(ApplicationChiasmusText)
   //CREATE_BODY_PART_FORMATTER(ApplicationPgp)
+  CREATE_BODY_PART_FORMATTER(ApplicationMsTnef)
 
   CREATE_BODY_PART_FORMATTER(MessageRfc822)
 
@@ -147,6 +148,7 @@
   { "x-pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
   { "vnd.de.bund.bsi.chiasmus-text", &ApplicationChiasmusTextBodyPartFormatter::create },
   { "pgp", &ApplicationPgpBodyPartFormatter::create },
+  { "ms-tnef", &ApplicationMsTnefBodyPartFormatter::create }
 };
 
 static const SubtypeBuiltin textSubtypeBuiltins[] = {
@@ -286,8 +288,8 @@
       break;
     case 'm':
     case 'M':
-      //if ( kasciistricmp( subtype, "ms-tnef" ) == 0 )
-      //  return ApplicationMsTnefBodyPartFormatter::create();
+      if ( kasciistricmp( subtype, "ms-tnef" ) == 0 )
+        return ApplicationMsTnefBodyPartFormatter::create();
       break;
     case 'v':
     case 'V':
--- branches/KDE/3.5/kdepim/kmail/kmreaderwin.cpp #650108:650109
@@ -1679,21 +1679,10 @@
     fileName = aMsgPart->name();
 
   //--- Sven's save attachments to /tmp start ---
-  KTempFile *tempFile = new KTempFile( QString::null,
-                                       "." + QString::number( aPartNum ) );
-  tempFile->setAutoDelete( true );
-  QString fname = tempFile->name();
-  delete tempFile;
+  QString fname = createTempDir( QString::number( aPartNum ) );
+  if ( fname.isEmpty() )
+    return QString();
 
-  if( ::access( QFile::encodeName( fname ), W_OK ) != 0 )
-    // Not there or not writable
-    if( ::mkdir( QFile::encodeName( fname ), 0 ) != 0
-        || ::chmod( QFile::encodeName( fname ), S_IRWXU ) != 0 )
-      return QString::null; //failed create
-
-  assert( !fname.isNull() );
-
-  mTempDirs.append( fname );
   // strip off a leading path
   int slashPos = fileName.findRev( '/' );
   if( -1 != slashPos )
@@ -1719,7 +1708,25 @@
   return fname;
 }
 
+QString KMReaderWin::createTempDir( const QString &param )
+{
+  KTempFile *tempFile = new KTempFile( QString::null, "." + param );
+  tempFile->setAutoDelete( true );
+  QString fname = tempFile->name();
+  delete tempFile;
 
+  if( ::access( QFile::encodeName( fname ), W_OK ) != 0 )
+    // Not there or not writable
+    if( ::mkdir( QFile::encodeName( fname ), 0 ) != 0
+        || ::chmod( QFile::encodeName( fname ), S_IRWXU ) != 0 )
+      return QString::null; //failed create
+
+  assert( !fname.isNull() );
+
+  mTempDirs.append( fname );
+  return fname;
+}
+
 //-----------------------------------------------------------------------------
 void KMReaderWin::showVCard( KMMessagePart * msgPart ) {
   const QString vCard = msgPart->bodyToUnicode( overrideCodec() );
--- branches/KDE/3.5/kdepim/kmail/kmreaderwin.h #650108:650109
@@ -65,7 +65,7 @@
   struct URLArgs;
 }
 
-/** 
+/**
    This class implements a "reader window", that is a window
    used for reading or viewing messages.
 */
@@ -406,6 +406,13 @@
   */
   QString writeMessagePartToTempFile( KMMessagePart* msgPart, int partNumber );
 
+  /**
+    Creates a temporary dir for saving attachments, etc.
+    Will be automatically deleted when another message is viewed.
+    @param param Optional part of the directory name.
+  */
+  QString createTempDir( const QString &param = QString() );
+
   /** show window containing infos about a vCard. */
   void showVCard(KMMessagePart *msgPart);
 
--- branches/KDE/3.5/kdepim/kmail/objecttreeparser.cpp #650108:650109
@@ -72,9 +72,14 @@
 #include <kpgp.h>
 #include <linklocator.h>
 
+#include <ktnef/ktnefparser.h>
+#include <ktnef/ktnefmessage.h>
+#include <ktnef/ktnefattach.h>
+
 // other KDE headers
 #include <kdebug.h>
 #include <klocale.h>
+#include <kmimetype.h>
 #include <kglobal.h>
 #include <khtml_part.h>
 #include <ktempfile.h>
@@ -86,6 +91,7 @@
 
 // other Qt headers
 #include <qtextcodec.h>
+#include <qdir.h>
 #include <qfile.h>
 #include <qapplication.h>
 #include <kstyle.h>
@@ -1703,6 +1709,73 @@
   return true;
 }
 
+bool ObjectTreeParser::processApplicationMsTnefSubtype( partNode *node, ProcessResult &result )
+{
+  Q_UNUSED( result );
+  if ( !mReader )
+    return false;
+
+  const QString fileName = mReader->writeMessagePartToTempFile( &node->msgPart(), node->nodeId() );
+  KTNEFParser parser;
+  if ( !parser.openFile( fileName ) || !parser.message()) {
+    kdDebug() << k_funcinfo << "Could not parse " << fileName << endl;
+    return false;
+  }
+
+  QPtrList<KTNEFAttach> tnefatts = parser.message()->attachmentList();
+  if ( tnefatts.isEmpty() ) {
+    kdDebug() << k_funcinfo << "No attachments found in " << fileName << endl;
+    return false;
+  }
+
+  if ( !showOnlyOneMimePart() ) {
+    QString label = node->msgPart().fileName().stripWhiteSpace();
+    if ( label.isEmpty() )
+      label = node->msgPart().name().stripWhiteSpace();
+    label = KMMessage::quoteHtmlChars( label, true );
+    const QString comment = KMMessage::quoteHtmlChars( node->msgPart().contentDescription(), true );
+    const QString dir = QApplication::reverseLayout() ? "rtl" : "ltr" ;
+
+    QString htmlStr = "<table cellspacing=\"1\" class=\"textAtm\">"
+                "<tr class=\"textAtmH\"><td dir=\"" + dir + "\">";
+    if ( !fileName.isEmpty() )
+      htmlStr += "<a href=\"" + QString("file:")
+        + KURL::encode_string( fileName ) + "\">"
+        + label + "</a>";
+    else
+      htmlStr += label;
+    if ( !comment.isEmpty() )
+      htmlStr += "<br>" + comment;
+    htmlStr += "</td></tr><tr class=\"textAtmB\"><td>";
+    htmlWriter()->queue( htmlStr );
+  }
+
+  for ( uint i = 0; i < tnefatts.count(); ++i ) {
+    KTNEFAttach *att = tnefatts.at( i );
+    QString label = att->displayName();
+    if( label.isEmpty() )
+      label = att->name();
+    label = KMMessage::quoteHtmlChars( label, true );
+
+    QString dir = mReader->createTempDir( "ktnef-" + QString::number( i ) );
+    parser.extractFileTo( att->name(), dir );
+    mReader->mTempFiles.append( dir + QDir::separator() + att->name() );
+    QString href = "file:" + KURL::encode_string( dir + QDir::separator() + att->name() );
+
+    KMimeType::Ptr mimeType = KMimeType::mimeType( att->mimeTag() );
+    QString iconName = KGlobal::instance()->iconLoader()->iconPath( mimeType->icon( QString(), false ), KIcon::Desktop );
+
+    htmlWriter()->queue( "<div><a href=\"" + href + "\"><img src=\"" +
+                          iconName + "\" border=\"0\" style=\"max-width: 100%\">" + label +
+                          "</a></div><br>" );
+  }
+
+  if ( !showOnlyOneMimePart() )
+    htmlWriter()->queue( "</td></tr></table>" );
+
+  return true;
+}
+
   void ObjectTreeParser::writeBodyString( const QCString & bodyString,
                                           const QString & fromAddress,
                                           const QTextCodec * codec,
--- branches/KDE/3.5/kdepim/kmail/objecttreeparser.h #650108:650109
@@ -2,7 +2,7 @@
     objecttreeparser.h
 
     This file is part of KMail, the KDE mail client.
-    Copyright (c) 2002-2003 Klar