00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035
00036 #include "headerstyle.h"
00037
00038 #include "headerstrategy.h"
00039 #include "kmkernel.h"
00040 #include "linklocator.h"
00041 #include "kmmessage.h"
00042 #include "spamheaderanalyzer.h"
00043 #include "globalsettings.h"
00044
00045 #include <libemailfunctions/email.h>
00046 #include <libkdepim/kxface.h>
00047 using namespace KPIM;
00048
00049 #include <mimelib/string.h>
00050 #include <mimelib/field.h>
00051 #include <mimelib/headers.h>
00052
00053 #include <kdebug.h>
00054 #include <klocale.h>
00055 #include <kglobal.h>
00056 #include <kimproxy.h>
00057 #include <kabc/stdaddressbook.h>
00058 #include <kabc/addresseelist.h>
00059 #include <kmdcodec.h>
00060 #include <qdatetime.h>
00061 #include <qbuffer.h>
00062 #include <qbitmap.h>
00063 #include <qimage.h>
00064 #include <qapplication.h>
00065 #include <qregexp.h>
00066
00067 #include <kstandarddirs.h>
00068
00069 namespace KMail {
00070
00071
00072
00073
00074 static inline QString directionOf( const QString & str ) {
00075 return str.isRightToLeft() ? "rtl" : "ltr" ;
00076 }
00077
00078 #if 0
00079
00080
00081
00082 static QString convertToHtmlBlock( const QString & str, bool useSpan=false ) {
00083 QString dir = directionOf( str );
00084 QString format = "<%1 dir=\"%3\">%4</%2>";
00085 return format.arg( useSpan ? "span" : "div" )
00086 .arg( useSpan ? "span" : "div" )
00087 .arg( dir )
00088 .arg( LinkLocator::convertToHtml( str ) );
00089 }
00090 #endif
00091
00092
00093 static QString strToHtml( const QString & str,
00094 int flags = LinkLocator::PreserveSpaces ) {
00095 return LinkLocator::convertToHtml( str, flags );
00096 }
00097
00098
00099
00100
00101
00102
00103 class BriefHeaderStyle : public HeaderStyle {
00104 friend class ::KMail::HeaderStyle;
00105 protected:
00106 BriefHeaderStyle() : HeaderStyle() {}
00107 virtual ~BriefHeaderStyle() {}
00108
00109 public:
00110 const char * name() const { return "brief"; }
00111 const HeaderStyle * next() const { return plain(); }
00112 const HeaderStyle * prev() const { return fancy(); }
00113
00114 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00115 const QString & vCardName, bool printing, bool topLevel ) const;
00116 };
00117
00118 QString BriefHeaderStyle::format( const KMMessage * message,
00119 const HeaderStrategy * strategy,
00120 const QString & vCardName, bool printing, bool topLevel ) const {
00121 if ( !message ) return QString::null;
00122 if ( !strategy )
00123 strategy = HeaderStrategy::brief();
00124
00125
00126
00127
00128 QString dir = QApplication::reverseLayout() ? "rtl" : "ltr" ;
00129
00130
00131
00132
00133
00134
00135
00136 QString subjectDir;
00137 if (!message->subject().isEmpty())
00138 subjectDir = directionOf( message->cleanSubject() );
00139 else
00140 subjectDir = directionOf( i18n("No Subject") );
00141
00142
00143 QString dateString;
00144 if( printing ) {
00145 QDateTime dateTime;
00146 KLocale * locale = KGlobal::locale();
00147 dateTime.setTime_t( message->date() );
00148 dateString = locale->formatDateTime( dateTime );
00149 } else {
00150 dateString = message->dateStr();
00151 }
00152
00153 QString headerStr = "<div class=\"header\" dir=\"" + dir + "\">\n";
00154
00155 if ( strategy->showHeader( "subject" ) )
00156 headerStr += "<div dir=\"" + subjectDir + "\">\n"
00157 "<b style=\"font-size:130%\">" +
00158 strToHtml( message->subject() ) +
00159 "</b></div>\n";
00160
00161 QStringList headerParts;
00162
00163 if ( strategy->showHeader( "from" ) ) {
00164 QString fromStr = message->from();
00165 if ( fromStr.isEmpty() )
00166 fromStr = message->fromStrip();
00167 QString fromPart = KMMessage::emailAddrAsAnchor( fromStr, true );
00168 if ( !vCardName.isEmpty() )
00169 fromPart += " <a href=\"" + vCardName + "\">" + i18n("[vCard]") + "</a>";
00170 headerParts << fromPart;
00171 }
00172
00173 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() )
00174 headerParts << i18n("CC: ") + KMMessage::emailAddrAsAnchor( message->cc(), true );
00175
00176 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() )
00177 headerParts << i18n("BCC: ") + KMMessage::emailAddrAsAnchor( message->bcc(), true );
00178
00179 if ( strategy->showHeader( "date" ) )
00180 headerParts << strToHtml(message->dateShortStr());
00181
00182
00183 headerStr += " (" + headerParts.grep( QRegExp( "\\S" ) ).join( ",\n" ) + ')';
00184
00185 headerStr += "</div>\n";
00186
00187
00188
00189 return headerStr;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198 class PlainHeaderStyle : public HeaderStyle {
00199 friend class ::KMail::HeaderStyle;
00200 protected:
00201 PlainHeaderStyle() : HeaderStyle() {}
00202 virtual ~PlainHeaderStyle() {}
00203
00204 public:
00205 const char * name() const { return "plain"; }
00206 const HeaderStyle * next() const { return fancy(); }
00207 const HeaderStyle * prev() const { return brief(); }
00208
00209 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00210 const QString & vCardName, bool printing, bool topLevel ) const;
00211
00212 private:
00213 QString formatAllMessageHeaders( const KMMessage * message ) const;
00214 };
00215
00216 QString PlainHeaderStyle::format( const KMMessage * message,
00217 const HeaderStrategy * strategy,
00218 const QString & vCardName, bool printing, bool topLevel ) const {
00219 if ( !message ) return QString::null;
00220 if ( !strategy )
00221 strategy = HeaderStrategy::rich();
00222
00223
00224
00225
00226 QString dir = ( QApplication::reverseLayout() ? "rtl" : "ltr" );
00227
00228
00229
00230
00231
00232
00233
00234 QString subjectDir;
00235 if (!message->subject().isEmpty())
00236 subjectDir = directionOf( message->cleanSubject() );
00237 else
00238 subjectDir = directionOf( i18n("No Subject") );
00239
00240
00241 QString dateString;
00242 if( printing ) {
00243 QDateTime dateTime;
00244 KLocale* locale = KGlobal::locale();
00245 dateTime.setTime_t( message->date() );
00246 dateString = locale->formatDateTime( dateTime );
00247 }
00248 else {
00249 dateString = message->dateStr();
00250 }
00251
00252 QString headerStr;
00253
00254 if ( strategy->headersToDisplay().isEmpty()
00255 && strategy->defaultPolicy() == HeaderStrategy::Display ) {
00256
00257
00258 headerStr= QString("<div class=\"header\" dir=\"ltr\">");
00259 headerStr += formatAllMessageHeaders( message );
00260 return headerStr + "</div>";
00261 }
00262
00263 headerStr = QString("<div class=\"header\" dir=\"%1\">").arg(dir);
00264
00265
00266 if ( strategy->showHeader( "subject" ) )
00267 headerStr += QString("<div dir=\"%1\"><b style=\"font-size:130%\">" +
00268 strToHtml(message->subject()) + "</b></div>\n")
00269 .arg(subjectDir);
00270
00271 if ( strategy->showHeader( "date" ) )
00272 headerStr.append(i18n("Date: ") + strToHtml(dateString)+"<br>\n");
00273
00274 #if 0
00275
00276 QString presence;
00277 QString kabcUid;
00278 if ( strategy->showHeader( "status" ) )
00279 {
00280 KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
00281 KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getFirstEmailAddress( message->from() ) );
00282 ::KIMProxy *imProxy = KMKernel::self()->imProxy();
00283 kabcUid = addresses[0].uid();
00284 presence = imProxy->presenceString( kabcUid );
00285 }
00286 #endif
00287
00288 if ( strategy->showHeader( "from" ) ) {
00289 QString fromStr = message->from();
00290 if ( fromStr.isEmpty() )
00291 fromStr = message->fromStrip();
00292 headerStr.append(i18n("From: ") +
00293 KMMessage::emailAddrAsAnchor( fromStr, false, "", true ) );
00294 if ( !vCardName.isEmpty() )
00295 headerStr.append(" <a href=\"" + vCardName +
00296 "\">" + i18n("[vCard]") + "</a>" );
00297 #if 0
00298 if ( !presence.isEmpty() && strategy->showHeader( "status" ) )
00299 headerStr.append(" (<span name=\"presence-" + kabcUid + "\">" + presence + "</span>)" );
00300 #endif
00301
00302 if ( strategy->showHeader( "organization" )
00303 && !message->headerField("Organization").isEmpty())
00304 headerStr.append(" (" +
00305 strToHtml(message->headerField("Organization")) + ")");
00306 headerStr.append("<br>\n");
00307 }
00308
00309 if ( strategy->showHeader( "to" ) )
00310 headerStr.append(i18n("To: ")+
00311 KMMessage::emailAddrAsAnchor(message->to(),false) + "<br>\n");
00312
00313 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() )
00314 headerStr.append(i18n("CC: ")+
00315 KMMessage::emailAddrAsAnchor(message->cc(),false) + "<br>\n");
00316
00317 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() )
00318 headerStr.append(i18n("BCC: ")+
00319 KMMessage::emailAddrAsAnchor(message->bcc(),false) + "<br>\n");
00320
00321 if ( strategy->showHeader( "reply-to" ) && !message->replyTo().isEmpty())
00322 headerStr.append(i18n("Reply to: ")+
00323 KMMessage::emailAddrAsAnchor(message->replyTo(),false) + "<br>\n");
00324
00325 headerStr += "</div>\n";
00326
00327 return headerStr;
00328 }
00329
00330 QString PlainHeaderStyle::formatAllMessageHeaders( const KMMessage * message ) const {
00331 const DwHeaders & headers = message->headers();
00332 QString result;
00333
00334 for ( const DwField * field = headers.FirstField() ; field ; field = field->Next() ) {
00335 result += ( field->FieldNameStr() + ": " ).c_str();
00336 result += strToHtml( field->FieldBodyStr().c_str() );
00337 result += "<br>\n";
00338 }
00339
00340 return result;
00341 }
00342
00343
00344
00345
00346
00347
00348 class FancyHeaderStyle : public HeaderStyle {
00349 friend class ::KMail::HeaderStyle;
00350 protected:
00351 FancyHeaderStyle() : HeaderStyle() {}
00352 virtual ~FancyHeaderStyle() {}
00353
00354 public:
00355 const char * name() const { return "fancy"; }
00356 const HeaderStyle * next() const { return enterprise(); }
00357 const HeaderStyle * prev() const { return plain(); }
00358
00359 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00360 const QString & vCardName, bool printing, bool topLevel ) const;
00361 static QString imgToDataUrl( const QImage & image,
00362 const char *fmt = "PNG" );
00363
00364 private:
00365 static QString drawSpamMeter( double percent, const QString & filterHeader );
00366
00367 };
00368
00369 QString FancyHeaderStyle::drawSpamMeter( double percent,
00370 const QString & filterHeader )
00371 {
00372 QImage meterBar( 20, 1, 8, 24 );
00373 const unsigned short gradient[20][3] = {
00374 { 0, 255, 0 },
00375 { 27, 254, 0 },
00376 { 54, 252, 0 },
00377 { 80, 250, 0 },
00378 { 107, 249, 0 },
00379 { 135, 247, 0 },
00380 { 161, 246, 0 },
00381 { 187, 244, 0 },
00382 { 214, 242, 0 },
00383 { 241, 241, 0 },
00384 { 255, 228, 0 },
00385 { 255, 202, 0 },
00386 { 255, 177, 0 },
00387 { 255, 151, 0 },
00388 { 255, 126, 0 },
00389 { 255, 101, 0 },
00390 { 255, 76, 0 },
00391 { 255, 51, 0 },
00392 { 255, 25, 0 },
00393 { 255, 0, 0 }
00394 };
00395 meterBar.setColor( 21, qRgb( 255, 255, 255 ) );
00396 meterBar.setColor( 22, qRgb( 170, 170, 170 ) );
00397 if ( percent < 0 )
00398 meterBar.fill( 22 );
00399 else {
00400 meterBar.fill( 21 );
00401 int max = QMIN( 20, static_cast<int>( percent ) / 5 );
00402 for ( int i = 0; i < max; ++i ) {
00403 meterBar.setColor( i+1, qRgb( gradient[i][0], gradient[i][1],
00404 gradient[i][2] ) );
00405 meterBar.setPixel( i, 0, i+1 );
00406 }
00407 }
00408 QString titleText = i18n("%1% probability of being spam.\n\nFull report:\n%2")
00409 .arg( QString::number( percent ), filterHeader );
00410 return QString("<img src=\"%1\" width=\"%2\" height=\"%3\" style=\"border: 1px solid black;\" title=\"%4\"> ")
00411 .arg( imgToDataUrl( meterBar, "PPM" ), QString::number( 20 ),
00412 QString::number( 5 ), titleText );
00413 }
00414
00415
00416 QString FancyHeaderStyle::format( const KMMessage * message,
00417 const HeaderStrategy * strategy,
00418 const QString & vCardName, bool printing, bool topLevel ) const {
00419 if ( !message ) return QString::null;
00420 if ( !strategy )
00421 strategy = HeaderStrategy::rich();
00422
00423 KConfigGroup configReader( KMKernel::config(), "Reader" );
00424
00425
00426
00427
00428
00429 QString dir = ( QApplication::reverseLayout() ? "rtl" : "ltr" );
00430 QString headerStr = QString("<div class=\"fancy header\" dir=\"%1\">\n").arg(dir);
00431
00432
00433
00434
00435
00436
00437
00438 QString subjectDir;
00439 if ( !message->subject().isEmpty() )
00440 subjectDir = directionOf( message->cleanSubject() );
00441 else
00442 subjectDir = directionOf( i18n("No Subject") );
00443
00444
00445 QString dateString;
00446 if( printing ) {
00447 QDateTime dateTime;
00448 KLocale* locale = KGlobal::locale();
00449 dateTime.setTime_t( message->date() );
00450 dateString = locale->formatDateTime( dateTime );
00451 }
00452 else {
00453 dateString = message->dateStr();
00454 }
00455
00456
00457
00458
00459
00460
00461 QString spamHTML;
00462
00463 if ( configReader.readBoolEntry( "showSpamStatus", true ) ) {
00464 SpamScores scores = SpamHeaderAnalyzer::getSpamScores( message );
00465 for ( SpamScoresIterator it = scores.begin(); it != scores.end(); ++it )
00466 spamHTML += (*it).agent() + " " +
00467 drawSpamMeter( (*it).score(), (*it).spamHeader() );
00468 }
00469
00470 QString userHTML;
00471 QString presence;
00472
00473
00474
00475 ::KIMProxy *imProxy = KMKernel::self()->imProxy();
00476 QString kabcUid;
00477 KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
00478 KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getFirstEmailAddress( message->from() ) );
00479
00480 QString photoURL;
00481 int photoWidth = 60;
00482 int photoHeight = 60;
00483 if( addresses.count() == 1 )
00484 {
00485
00486 kabcUid = addresses[0].uid();
00487
00488 if ( imProxy->initialize() ) {
00489
00490 presence = imProxy->presenceString( kabcUid );
00491 if ( !presence.isEmpty() )
00492 {
00493 QString presenceIcon = QString::fromLatin1( " <img src=\"%1\"/>" )
00494 .arg( imgToDataUrl( imProxy->presenceIcon( kabcUid ).convertToImage() ) );
00495 presence += presenceIcon;
00496 }
00497 }
00498
00499 if ( addresses[0].photo().isIntern() )
00500 {
00501
00502
00503 QImage photo = addresses[0].photo().data();
00504 if ( !photo.isNull() )
00505 {
00506 photoWidth = photo.width();
00507 photoHeight = photo.height();
00508
00509 if ( photoHeight > 60 ) {
00510 double ratio = ( double )photoHeight / ( double )photoWidth;
00511 photoHeight = 60;
00512 photoWidth = (int)( 60 / ratio );
00513 photo = photo.smoothScale( photoWidth, photoHeight );
00514 }
00515 photoURL = imgToDataUrl( photo );
00516 }
00517 }
00518 else
00519 {
00520
00521 photoURL = addresses[0].photo().url();
00522 if ( photoURL.startsWith("/") )
00523 photoURL.prepend( "file:" );
00524 }
00525 }
00526 else
00527 {
00528 kdDebug( 5006 ) << "Multiple / No addressees matched email address; Count is " << addresses.count() << endl;
00529 userHTML = " ";
00530 }
00531
00532 if( photoURL.isEmpty() ) {
00533
00534 QString faceheader = message->headerField( "Face" );
00535 if ( !faceheader.isEmpty() ) {
00536 QImage faceimage;
00537
00538 kdDebug( 5006 ) << "Found Face: header" << endl;
00539
00540 QCString facestring = faceheader.utf8();
00541
00542
00543 if ( facestring.length() < 993 ) {
00544 QByteArray facearray;
00545 KCodecs::base64Decode(facestring, facearray);
00546
00547 QImage faceimage;
00548 if ( faceimage.loadFromData( facearray, "png" ) ) {
00549
00550 if ( (48 == faceimage.width()) && (48 == faceimage.height()) ) {
00551 photoURL = imgToDataUrl( faceimage );
00552 photoWidth = 48;
00553 photoHeight = 48;
00554 } else {
00555 kdDebug( 5006 ) << "Face: header image is" << faceimage.width() << "by" << faceimage.height() <<"not 48x48 Pixels" << endl;
00556 }
00557 } else {
00558 kdDebug( 5006 ) << "Failed to load decoded png from Face: header" << endl;
00559 }
00560 } else {
00561 kdDebug( 5006 ) << "Face: header too long at " << facestring.length() << endl;
00562 }
00563 }
00564 }
00565
00566 if( photoURL.isEmpty() )
00567 {
00568
00569 QString xfaceURL;
00570 QString xfhead = message->headerField( "X-Face" );
00571 if ( !xfhead.isEmpty() )
00572 {
00573 KXFace xf;
00574 photoURL = imgToDataUrl( xf.toImage( xfhead ) );
00575 photoWidth = 48;
00576 photoHeight = 48;
00577
00578 }
00579 }
00580
00581 if( !photoURL.isEmpty() )
00582 {
00583
00584 userHTML = QString("<img src=\"%1\" width=\"%2\" height=\"%3\">")
00585 .arg( photoURL ).arg( photoWidth ).arg( photoHeight );
00586 if ( presence.isEmpty() ) {
00587 userHTML = QString("<div class=\"senderpic\">") + userHTML + "</div>";
00588 } else {
00589 userHTML = QString( "<div class=\"senderpic\">"
00590 "<a href=\"im:%1\">%2<div class=\"senderstatus\">"
00591 "<span name=\"presence-%3\">%4</span></div></a>"
00592 "</div>" ).arg( kabcUid )
00593 .arg( userHTML )
00594 .arg( kabcUid )
00595 .arg( presence );
00596 }
00597 } else {
00598
00599 if ( !presence.isEmpty() )
00600 userHTML = QString( "<a href=\"im:%1\"><div class=\"senderstatus\">"
00601 "<span name=\"presence-%2\">%3</span></div></a>" )
00602 .arg( kabcUid )
00603 .arg( kabcUid )
00604 .arg( presence );
00605 }
00606 #if 0
00607
00608 if ( imProxy->imAppsAvailable() )
00609 presence = "<a name=\"launchim\" href=\"kmail:startIMApp\">" + i18n("Launch IM") + "</a></span>";
00610
00611
00612 kdDebug( 5006 ) << "final presence: '" << presence << "'" << endl;
00613 #endif
00614
00615
00616
00617
00618 if ( strategy->showHeader( "subject" ) ) {
00619 const int flags = LinkLocator::PreserveSpaces |
00620 ( GlobalSettings::self()->showEmoticons() ?
00621 LinkLocator::ReplaceSmileys : 0 );
00622 headerStr += QString("<div dir=\"%1\">%2</div>\n")
00623 .arg(subjectDir)
00624 .arg(message->subject().isEmpty()?
00625 i18n("No Subject") :
00626 strToHtml( message->subject(), flags ));
00627 }
00628 headerStr += "<table class=\"outer\"><tr><td width=\"100%\"><table>\n";
00629
00630
00631
00632
00633 if ( strategy->showHeader( "from" ) ) {
00634 QString fromStr = message->from();
00635 if ( fromStr.isEmpty() )
00636 fromStr = message->fromStrip();
00637 headerStr += QString("<tr><th>%1</th>\n"
00638 "<td>")
00639 .arg(i18n("From: "))
00640 + KMMessage::emailAddrAsAnchor( fromStr, false )
00641 + ( !message->headerField( "Resent-From" ).isEmpty() ? " "
00642 + i18n("(resent from %1)")
00643 .arg( KMMessage::emailAddrAsAnchor(
00644 message->headerField( "Resent-From" ),false) )
00645 : QString("") )
00646 + ( !vCardName.isEmpty() ? " <a href=\"" + vCardName + "\">"
00647 + i18n("[vCard]") + "</a>"
00648 : QString("") )
00649 #if 0
00650 + ( ( !presence.isEmpty() )
00651 ? " (<span name=\"presence-" + kabcUid + "\">" + presence + "</span>)"
00652 : QString("") )
00653 #endif
00654 + ( message->headerField("Organization").isEmpty()
00655 ? QString("")
00656 : " ("
00657 + strToHtml(message->headerField("Organization"))
00658 + ")")
00659 + "</td></tr>\n";
00660 }
00661
00662 if ( strategy->showHeader( "to" ) )
00663 headerStr.append(QString("<tr><th>%1</th>\n"
00664 "<td>%2</td></tr>\n")
00665 .arg(i18n("To: "))
00666 .arg(KMMessage::emailAddrAsAnchor(message->to(),false)));
00667
00668
00669 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty())
00670 headerStr.append(QString("<tr><th>%1</th>\n"
00671 "<td>%2</td></tr>\n")
00672 .arg(i18n("CC: "))
00673 .arg(KMMessage::emailAddrAsAnchor(message->cc(),false)));
00674
00675
00676 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty())
00677 headerStr.append(QString("<tr><th>%1</th>\n"
00678 "<td>%2</td></tr>\n")
00679 .arg(i18n("BCC: "))
00680 .arg(KMMessage::emailAddrAsAnchor(message->bcc(),false)));
00681
00682 if ( strategy->showHeader( "date" ) )
00683 headerStr.append(QString("<tr><th>%1</th>\n"
00684 "<td dir=\"%2\">%3</td></tr>\n")
00685 .arg(i18n("Date: "))
00686 .arg( directionOf( message->dateStr() ) )
00687 .arg(strToHtml(dateString)));
00688
00689 if ( GlobalSettings::self()->showUserAgent() ) {
00690 if ( strategy->showHeader( "user-agent" ) ) {
00691 if ( !message->headerField("User-Agent").isEmpty() ) {
00692 headerStr.append(QString("<tr><th>%1</th>\n"
00693 "<td>%2</td></tr>\n")
00694 .arg(i18n("User-Agent: "))
00695 .arg( strToHtml( message->headerField("User-Agent") ) ) );
00696 }
00697 }
00698
00699 if ( strategy->showHeader( "x-mailer" ) ) {
00700 if ( !message->headerField("X-Mailer").isEmpty() ) {
00701 headerStr.append(QString("<tr><th>%1</th>\n"
00702 "<td>%2</td></tr>\n")
00703 .arg(i18n("X-Mailer: "))
00704 .arg( strToHtml( message->headerField("X-Mailer") ) ) );
00705 }
00706 }
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 headerStr.append( QString("<tr><td colspan=\"2\"><div id=\"attachmentInjectionPoint\"></div></td></tr>" ) );
00718 headerStr.append(
00719 QString( "</table></td><td align=\"center\">%1</td></tr></table>\n" ).arg(userHTML) );
00720
00721 if ( !spamHTML.isEmpty() )
00722 headerStr.append( QString( "<div class=\"spamheader\" dir=\"%1\"><b>%2</b> <span style=\"padding-left: 20px;\">%3</span></div>\n")
00723 .arg( subjectDir, i18n("Spam Status:"), spamHTML ) );
00724
00725 headerStr += "</div>\n\n";
00726 return headerStr;
00727 }
00728
00729 QString FancyHeaderStyle::imgToDataUrl( const QImage &image, const char* fmt )
00730 {
00731 QByteArray ba;
00732 QBuffer buffer( ba );
00733 buffer.open( IO_WriteOnly );
00734 image.save( &buffer, fmt );
00735 return QString::fromLatin1("data:image/%1;base64,%2")
00736 .arg( fmt, KCodecs::base64Encode( ba ) );
00737 }
00738
00739
00740
00741 class EnterpriseHeaderStyle : public HeaderStyle {
00742 friend class ::KMail::HeaderStyle;
00743 protected:
00744 EnterpriseHeaderStyle() : HeaderStyle() {}
00745 virtual ~EnterpriseHeaderStyle() {}
00746
00747 public:
00748 const char * name() const { return "enterprise"; }
00749 const HeaderStyle * next() const { return brief(); }
00750 const HeaderStyle * prev() const { return fancy(); }
00751
00752 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00753 const QString & vCardName, bool printing, bool topLevel ) const;
00754 };
00755
00756 QString EnterpriseHeaderStyle::format( const KMMessage * message,
00757 const HeaderStrategy * strategy,
00758 const QString & vCardName, bool printing, bool topLevel ) const {
00759 if ( !message ) return QString::null;
00760 if ( !strategy )
00761 strategy = HeaderStrategy::brief();
00762
00763
00764
00765
00766 QString dir = QApplication::reverseLayout() ? "rtl" : "ltr" ;
00767
00768
00769
00770
00771
00772
00773
00774 QString subjectDir;
00775 if (!message->subject().isEmpty())
00776 subjectDir = directionOf( message->cleanSubject() );
00777 else
00778 subjectDir = directionOf( i18n("No Subject") );
00779
00780
00781 QColor fontColor(Qt::white);
00782 QString linkColor = "class =\"white\"";
00783 const QColor activeColor = qApp->palette().active().highlight();
00784 QColor activeColorDark = activeColor.dark(130);
00785
00786 if( !topLevel ){
00787 activeColorDark = activeColor.dark(50);
00788 fontColor = qApp->palette().active().text();
00789 linkColor = "";
00790 }
00791
00792 QStringList headerParts;
00793 if( strategy->showHeader( "to" ) )
00794 headerParts << KMMessage::emailAddrAsAnchor( message->to(), false, linkColor );
00795
00796 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() )
00797 headerParts << i18n("CC: ") + KMMessage::emailAddrAsAnchor( message->cc(), true, linkColor );
00798
00799 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() )
00800 headerParts << i18n("BCC: ") + KMMessage::emailAddrAsAnchor( message->bcc(), true, linkColor );
00801
00802
00803 QString headerPart = " " + headerParts.grep( QRegExp( "\\S" ) ).join( ", " );
00804
00805
00806 QString dateString;
00807 if( printing ) {
00808 QDateTime dateTime;
00809 KLocale * locale = KGlobal::locale();
00810 dateTime.setTime_t( message->date() );
00811 dateString = locale->formatDateTime( dateTime );
00812 } else {
00813 dateString = message->dateStr();
00814 }
00815
00816 QString imgpath(locate("data","kmail/pics/"));
00817 imgpath.append("enterprise_");
00818 const QString borderSettings(" padding-top: 0px; padding-bottom: 0px; border-width: 0px ");
00819 QString headerStr ("");
00820
00821
00822 if(topLevel)
00823 headerStr +=
00824 "<div style=\"position: fixed; top: 0px; left: 0px; background-color: #606060; "
00825 "background-image: url("+imgpath+"shadow_left.png); width: 10px; min-height: 100%;\"> </div>"
00826 "<div style=\"position: fixed; top: 0px; right: 0px; background-color: #606060; "
00827 "background-image: url("+imgpath+"shadow_right.png); width: 10px; min-height: 100%;\"> </div>";
00828
00829 headerStr += ""
00830 "<div style=\"margin-left: 8px; top: 0px;\"><span style=\"font-size: 10px; font-weight: bold;\">"+dateString+"</span></div>"
00831
00832 "<table style=\"background: "+activeColorDark.name()+"; border-collapse:collapse; top: 14px; min-width: 200px; \" cellpadding=0> \n"
00833 " <tr> \n"
00834 " <td style=\"min-width: 6px; background-image: url("+imgpath+"top_left.png); \"></td> \n"
00835 " <td style=\"height: 6px; width: 100%; background: url("+imgpath+"top.png); \"></td> \n"
00836 " <td style=\"min-width: 6px; background: url("+imgpath+"top_right.png); \"></td> </tr> \n"
00837 " <tr> \n"
00838 " <td style=\"min-width: 6px; max-width: 6px; background: url("+imgpath+"left.png); \"></td> \n"
00839 " <td style=\"\"> \n"
00840 " <table style=\"color: "+fontColor.name()+" ! important; margin: 1px; border-spacing: 0px;\" cellpadding=0> \n";
00841
00842
00843
00844 if ( strategy->showHeader( "subject" ) ){
00845 headerStr +=
00846 " <tr> \n"
00847 " <td style=\"font-size: 6px; text-align: right; padding-left: 5px; padding-right: 24px; "+borderSettings+"\"></td> \n"
00848 " <td style=\"font-weight: bolder; font-size: 120%;"+borderSettings+"\">"+message->subject()+"</td> \n"
00849 " </tr> \n";
00850 }
00851
00852
00853 if ( strategy->showHeader( "from" ) ){
00854 QString fromStr = message->from();
00855 if ( fromStr.isEmpty() )
00856 fromStr = message->fromStrip();
00857
00858 QString fromPart = KMMessage::emailAddrAsAnchor( fromStr, true, linkColor );
00859 if ( !vCardName.isEmpty() )
00860 fromPart += " <a href=\"" + vCardName + "\" "+linkColor+">" + i18n("[vCard]") + "</a>";
00861
00862
00863 headerStr +=
00864 " <tr> \n"
00865 " <td style=\"font-size: 6px; padding-left: 5px; padding-right: 24px; text-align: right; "+borderSettings+"\">"+i18n("From: ")+"</td> \n"
00866 " <td style=\""+borderSettings+"\">"+ fromPart +"</td> "
00867 " </tr> ";
00868 }
00869
00870
00871 headerStr +=
00872 " <tr> "
00873 " <td style=\"font-size: 6px; text-align: right; padding-left: 5px; padding-right: 24px; "+borderSettings+"\">"+i18n("To: ")+"</td> "
00874 " <td style=\""+borderSettings+"\">"
00875 +headerPart+
00876 " </td> "
00877 " </tr> ";
00878
00879
00880 headerStr +=
00881 " </table> \n"
00882 " </td> \n"
00883 " <td style=\"min-width: 6px; max-height: 15px; background: url("+imgpath+"right.png); \"></td> \n"
00884 " </tr> \n"
00885 " <tr> \n"
00886 " <td style=\"min-width: 6px; background: url("+imgpath+"s_left.png); \"></td> \n"
00887 " <td style=\"height: 35px; width: 80%; background: url("+imgpath+"sbar.png);\"> \n"
00888 " <img src=\""+imgpath+"sw.png\" style=\"margin: 0px; height: 30px; overflow:hidden; \"> \n"
00889 " <img src=\""+imgpath+"sp_right.png\" style=\"float: right; \"> </td> \n"
00890 " <td style=\"min-width: 6px; background: url("+imgpath+"s_right.png); \"></td> \n"
00891 " </tr> \n"
00892 " </table> \n";
00893
00894
00895 if(topLevel) {
00896 headerStr +=
00897 "<div class=\"noprint\" style=\"position: absolute; top: -14px; right: 30px; width: 91px; height: 91px;\">\n"
00898 "<img style=\"float: right;\" src=\""+imgpath+"icon.png\">\n"
00899 "</div>\n";
00900
00901
00902 headerStr +=
00903 "<div class=\"noprint\" style=\"position: fixed; top: 60px; right: 20px; width: 91px; height: 200px;\">"
00904 "<div id=\"attachmentInjectionPoint\"></div>"
00905 "</div>\n";
00906 }
00907
00908 headerStr += "<div style=\"padding: 6px;\">";
00909
00910
00911
00912
00913
00914 return headerStr;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923 HeaderStyle::HeaderStyle() {
00924
00925 }
00926
00927 HeaderStyle::~HeaderStyle() {
00928
00929 }
00930
00931 const HeaderStyle * HeaderStyle::create( Type type ) {
00932 switch ( type ) {
00933 case Brief: return brief();
00934 case Plain: return plain();
00935 case Fancy: return fancy();
00936 case Enterprise: return enterprise();
00937 }
00938 kdFatal( 5006 ) << "HeaderStyle::create(): Unknown header style ( type == "
00939 << (int)type << " ) requested!" << endl;
00940 return 0;
00941 }
00942
00943 const HeaderStyle * HeaderStyle::create( const QString & type ) {
00944 QString lowerType = type.lower();
00945 if ( lowerType == "brief" ) return brief();
00946 if ( lowerType == "plain" ) return plain();
00947 if ( lowerType == "enterprise" ) return enterprise();
00948
00949
00950
00951 return fancy();
00952 }
00953
00954 static const HeaderStyle * briefStyle = 0;
00955 static const HeaderStyle * plainStyle = 0;
00956 static const HeaderStyle * fancyStyle = 0;
00957 static const HeaderStyle * enterpriseStyle = 0;
00958
00959 const HeaderStyle * HeaderStyle::brief() {
00960 if ( !briefStyle )
00961 briefStyle = new BriefHeaderStyle();
00962 return briefStyle;
00963 }
00964
00965 const HeaderStyle * HeaderStyle::plain() {
00966 if ( !plainStyle )
00967 plainStyle = new PlainHeaderStyle();
00968 return plainStyle;
00969 }
00970
00971 const HeaderStyle * HeaderStyle::fancy() {
00972 if ( !fancyStyle )
00973 fancyStyle = new FancyHeaderStyle();
00974 return fancyStyle;
00975 }
00976
00977 const HeaderStyle * HeaderStyle::enterprise() {
00978 if ( !enterpriseStyle )
00979 enterpriseStyle = new EnterpriseHeaderStyle();
00980 return enterpriseStyle;
00981 }
00982
00983 }