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. 6
      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

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

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

@ -33,6 +33,7 @@
#ifndef __KMAIL_INTERFACES_HTMLWRITER_H__
#define __KMAIL_INTERFACES_HTMLWRITER_H__
class QCString;
class QString;
namespace KMail {
@ -106,6 +107,11 @@ namespace KMail {
virtual void queue( const QString & str ) = 0;
/** (Start) flushing internal buffers, if any. */
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

@ -37,6 +37,10 @@
#include <khtml_part.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>
@ -61,6 +65,8 @@ namespace KMail {
reset();
}
mEmbeddedPartMap.clear();
// clear the widget:
mHtmlPart->view()->setUpdatesEnabled( false );
mHtmlPart->view()->viewport()->setUpdatesEnabled( false );
@ -75,6 +81,9 @@ namespace KMail {
void KHtmlPartHtmlWriter::end() {
kdWarning( mState != Begun, 5006 ) << "KHtmlPartHtmlWriter: end() called on non-begun or queued session!" << endl;
mHtmlPart->end();
resolveCidUrls();
mHtmlPart->view()->viewport()->setUpdatesEnabled( true );
mHtmlPart->view()->setUpdatesEnabled( true );
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

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

@ -2903,6 +2903,12 @@ void KMMessage::bodyPart(DwBodyPart* aDwBodyPart, KMMessagePart* aPart,
else
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,
// set all MultipartBodyPart attributes to empty values.
@ -2917,6 +2923,7 @@ void KMMessage::bodyPart(DwBodyPart* aDwBodyPart, KMMessagePart* aPart,
aPart->setContentDescription("");
aPart->setContentDisposition("");
aPart->setBody("");
aPart->setContentId("");
}
}

@ -112,6 +112,10 @@ public:
int subtype() const;
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.
If autoDecode is TRUE the decoded body will be used for mime type
determination (this does not change the body itself). */
@ -213,6 +217,7 @@ protected:
QCString mCte;
QCString mContentDescription;
QCString mContentDisposition;
QCString mContentId;
QByteArray mBody;
QCString mAdditionalCTypeParamStr;
QString mName;

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

@ -90,4 +90,9 @@ namespace KMail {
(*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

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

Loading…
Cancel
Save