Fix displaying HTML messages with embedded images. Patch by Aurélien Gâteau.

BUG:6710

svn path=/branches/KDE/3.5/kdepim/; revision=454999
wilder-work
Ingo Klcker 21 years ago
parent 341abac138
commit 37fd00aaff
  1. 4
      filehtmlwriter.cpp
  2. 1
      filehtmlwriter.h
  3. 6
      interfaces/htmlwriter.h
  4. 29
      khtmlparthtmlwriter.cpp
  5. 7
      khtmlparthtmlwriter.h
  6. 7
      kmmessage.cpp
  7. 5
      kmmsgpart.h
  8. 5
      objecttreeparser.cpp
  9. 5
      teehtmlwriter.cpp
  10. 1
      teehtmlwriter.h

@ -99,6 +99,10 @@ namespace KMail {
mStream.setDevice( &mFile ); mStream.setDevice( &mFile );
} }
void FileHtmlWriter::embedPart( const QCString & contentId, const QString & url ) {
mStream << "<!-- embedPart(contentID=" << contentId << ", url=" << url << ") -->" << endl;
flush();
}
} // namespace KMail } // namespace KMail

@ -52,6 +52,7 @@ namespace KMail {
void write( const QString & str ); void write( const QString & str );
void queue( const QString & str ); void queue( const QString & str );
void flush(); void flush();
void embedPart( const QCString & contentId, const QString & url );
private: private:
void openOrWarn(); void openOrWarn();

@ -33,6 +33,7 @@
#ifndef __KMAIL_INTERFACES_HTMLWRITER_H__ #ifndef __KMAIL_INTERFACES_HTMLWRITER_H__
#define __KMAIL_INTERFACES_HTMLWRITER_H__ #define __KMAIL_INTERFACES_HTMLWRITER_H__
class QCString;
class QString; class QString;
namespace KMail { namespace KMail {
@ -106,6 +107,11 @@ namespace KMail {
virtual void queue( const QString & str ) = 0; virtual void queue( const QString & str ) = 0;
/** (Start) flushing internal buffers, if any. */ /** (Start) flushing internal buffers, if any. */
virtual void flush() = 0; virtual void flush() = 0;
/**
* Embed a part with Content-ID @contentId, using url @url.
*/
virtual void embedPart( const QCString & contentId, const QString & url ) = 0;
}; };
} // namespace KMail } // namespace KMail

@ -37,6 +37,10 @@
#include <khtml_part.h> #include <khtml_part.h>
#include <khtmlview.h> #include <khtmlview.h>
#include <dom/dom_string.h>
#include <dom/html_document.h>
#include <dom/html_image.h>
#include <dom/html_misc.h>
#include <cassert> #include <cassert>
@ -61,6 +65,8 @@ namespace KMail {
reset(); reset();
} }
mEmbeddedPartMap.clear();
// clear the widget: // clear the widget:
mHtmlPart->view()->setUpdatesEnabled( false ); mHtmlPart->view()->setUpdatesEnabled( false );
mHtmlPart->view()->viewport()->setUpdatesEnabled( false ); mHtmlPart->view()->viewport()->setUpdatesEnabled( false );
@ -75,6 +81,9 @@ namespace KMail {
void KHtmlPartHtmlWriter::end() { void KHtmlPartHtmlWriter::end() {
kdWarning( mState != Begun, 5006 ) << "KHtmlPartHtmlWriter: end() called on non-begun or queued session!" << endl; kdWarning( mState != Begun, 5006 ) << "KHtmlPartHtmlWriter: end() called on non-begun or queued session!" << endl;
mHtmlPart->end(); mHtmlPart->end();
resolveCidUrls();
mHtmlPart->view()->viewport()->setUpdatesEnabled( true ); mHtmlPart->view()->viewport()->setUpdatesEnabled( true );
mHtmlPart->view()->setUpdatesEnabled( true ); mHtmlPart->view()->setUpdatesEnabled( true );
mHtmlPart->view()->viewport()->repaint( false ); mHtmlPart->view()->viewport()->repaint( false );
@ -118,7 +127,27 @@ namespace KMail {
} }
} }
void KHtmlPartHtmlWriter::embedPart( const QCString & contentId,
const QString & contentURL ) {
mEmbeddedPartMap[QString(contentId)] = contentURL;
}
void KHtmlPartHtmlWriter::resolveCidUrls()
{
DOM::HTMLDocument document = mHtmlPart->htmlDocument();
DOM::HTMLCollection images = document.images();
for ( DOM::Node node = images.firstItem(); !node.isNull(); node = images.nextItem() ) {
DOM::HTMLImageElement image( node );
KURL url( image.src().string() );
if ( url.protocol() == "cid" ) {
EmbeddedPartMap::const_iterator it = mEmbeddedPartMap.find( url.path() );
if ( it != mEmbeddedPartMap.end() ) {
kdDebug(5006) << "Replacing " << url.prettyURL() << " by " << it.data() << endl;
image.setSrc( it.data() );
}
}
}
}
} // namespace KMail } // namespace KMail

@ -46,6 +46,8 @@ namespace KMail {
class KHtmlPartHtmlWriter : public QObject, public HtmlWriter { class KHtmlPartHtmlWriter : public QObject, public HtmlWriter {
Q_OBJECT Q_OBJECT
public: public:
// Key is Content-Id, value is URL
typedef QMap<QString, QString> EmbeddedPartMap;
KHtmlPartHtmlWriter( KHTMLPart * part, KHtmlPartHtmlWriter( KHTMLPart * part,
QObject * parent=0, const char * name = 0 ); QObject * parent=0, const char * name = 0 );
virtual ~KHtmlPartHtmlWriter(); virtual ~KHtmlPartHtmlWriter();
@ -56,10 +58,14 @@ namespace KMail {
void write( const QString & str ); void write( const QString & str );
void queue( const QString & str ); void queue( const QString & str );
void flush(); void flush();
void embedPart( const QCString & contentId, const QString & url );
private slots: private slots:
void slotWriteNextHtmlChunk(); void slotWriteNextHtmlChunk();
private:
void resolveCidUrls();
private: private:
KHTMLPart * mHtmlPart; KHTMLPart * mHtmlPart;
QStringList mHtmlQueue; QStringList mHtmlQueue;
@ -69,6 +75,7 @@ namespace KMail {
Queued, Queued,
Ended Ended
} mState; } mState;
EmbeddedPartMap mEmbeddedPartMap;
}; };
} // namespace KMail } // namespace KMail

@ -2903,6 +2903,12 @@ void KMMessage::bodyPart(DwBodyPart* aDwBodyPart, KMMessagePart* aPart,
else else
aPart->setBody( "" ); aPart->setBody( "" );
// Content-id
if ( headers.HasContentId() ) {
const QCString contentId = headers.ContentId().AsString().c_str();
// ignore leading '<' and trailing '>'
aPart->setContentId( contentId.mid( 1, contentId.length() - 2 ) );
}
} }
// If no valid body part was given, // If no valid body part was given,
// set all MultipartBodyPart attributes to empty values. // set all MultipartBodyPart attributes to empty values.
@ -2917,6 +2923,7 @@ void KMMessage::bodyPart(DwBodyPart* aDwBodyPart, KMMessagePart* aPart,
aPart->setContentDescription(""); aPart->setContentDescription("");
aPart->setContentDisposition(""); aPart->setContentDisposition("");
aPart->setBody(""); aPart->setBody("");
aPart->setContentId("");
} }
} }

@ -112,6 +112,10 @@ public:
int subtype() const; int subtype() const;
void setSubtype(int aSubtype); void setSubtype(int aSubtype);
/** Content-Id */
QCString contentId() const { return mContentId; }
void setContentId( const QCString & aStr ) { mContentId = aStr; }
/** Set the 'Content-Type' by mime-magic from the contents of the body. /** Set the 'Content-Type' by mime-magic from the contents of the body.
If autoDecode is TRUE the decoded body will be used for mime type If autoDecode is TRUE the decoded body will be used for mime type
determination (this does not change the body itself). */ determination (this does not change the body itself). */
@ -213,6 +217,7 @@ protected:
QCString mCte; QCString mCte;
QCString mContentDescription; QCString mContentDescription;
QCString mContentDisposition; QCString mContentDisposition;
QCString mContentId;
QByteArray mBody; QByteArray mBody;
QCString mAdditionalCTypeParamStr; QCString mAdditionalCTypeParamStr;
QString mName; QString mName;

@ -1765,6 +1765,11 @@ bool ObjectTreeParser::processApplicationChiasmusTextSubtype( partNode * curNode
} }
} }
QCString contentId = msgPart->contentId();
if ( !contentId.isEmpty() ) {
htmlWriter()->embedPart( contentId, href );
}
if( inlineImage ) if( inlineImage )
// show the filename of the image below the embedded image // show the filename of the image below the embedded image
htmlWriter()->queue( "<div><a href=\"" + href + "\">" htmlWriter()->queue( "<div><a href=\"" + href + "\">"

@ -90,4 +90,9 @@ namespace KMail {
(*it)->flush(); (*it)->flush();
} }
void TeeHtmlWriter::embedPart( const QCString & contentId, const QString & url ) {
for ( QValueListIterator<HtmlWriter*> it = mWriters.begin(); it != mWriters.end(); ++it )
(*it)->embedPart( contentId, url );
}
} // namespace KMail } // namespace KMail

@ -59,6 +59,7 @@ namespace KMail {
void write( const QString & str ); void write( const QString & str );
void queue( const QString & str ); void queue( const QString & str );
void flush(); void flush();
void embedPart( const QCString & contentId, const QString & url );
private: private:
/** We own the HtmlWriters added to us! */ /** We own the HtmlWriters added to us! */

Loading…
Cancel
Save