headerstyle.cpp
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 "linklocator.h"
00040 #include "kmmessage.h"
00041 #include "kmkernel.h"
00042
00043 #include <libkdepim/email.h>
00044
00045 #include <mimelib/string.h>
00046 #include <mimelib/field.h>
00047 #include <mimelib/headers.h>
00048
00049 #include <kdebug.h>
00050 #include <klocale.h>
00051 #include <kglobal.h>
00052 #include "kimproxy.h"
00053 #include <kabc/stdaddressbook.h>
00054 #include <kabc/addresseelist.h>
00055 #include <kmdcodec.h>
00056 #include <qdatetime.h>
00057 #include <qbuffer.h>
00058 #include <qimage.h>
00059 #include <qapplication.h>
00060 #include <qregexp.h>
00061
00062 namespace KMail {
00063
00064
00065
00066
00067 static inline QString directionOf( const QString & str ) {
00068 return str.isRightToLeft() ? "rtl" : "ltr" ;
00069 }
00070
00071 #if 0
00072
00073
00074
00075 static QString convertToHtmlBlock( const QString & str, bool useSpan=false ) {
00076 QString dir = directionOf( str );
00077 QString format = "<%1 dir=\"%3\">%4</%2>";
00078 return format.arg( useSpan ? "span" : "div" )
00079 .arg( useSpan ? "span" : "div" )
00080 .arg( dir )
00081 .arg( LinkLocator::convertToHtml( str ) );
00082 }
00083 #endif
00084
00085
00086 static QString strToHtml( const QString & str, bool preserveBlanks=true ) {
00087 return LinkLocator::convertToHtml( str, preserveBlanks );
00088 }
00089
00090
00091
00092
00093
00094
00095 class BriefHeaderStyle : public HeaderStyle {
00096 friend class HeaderStyle;
00097 protected:
00098 BriefHeaderStyle() : HeaderStyle() {}
00099 virtual ~BriefHeaderStyle() {}
00100
00101 public:
00102 const char * name() const { return "brief"; }
00103 const HeaderStyle * next() const { return plain(); }
00104 const HeaderStyle * prev() const { return fancy(); }
00105
00106 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00107 const QString & vCardName, bool printing ) const;
00108 };
00109
00110 QString BriefHeaderStyle::format( const KMMessage * message,
00111 const HeaderStrategy * strategy,
00112 const QString & vCardName, bool printing ) const {
00113 if ( !message ) return QString::null;
00114 if ( !strategy )
00115 strategy = HeaderStrategy::brief();
00116
00117
00118
00119
00120 QString dir = QApplication::reverseLayout() ? "rtl" : "ltr" ;
00121
00122
00123
00124
00125
00126
00127
00128 QString subjectDir;
00129 if (!message->subject().isEmpty())
00130 subjectDir = directionOf( message->cleanSubject() );
00131 else
00132 subjectDir = directionOf( i18n("No Subject") );
00133
00134
00135 QString dateString;
00136 if( printing ) {
00137 QDateTime dateTime;
00138 KLocale * locale = KGlobal::locale();
00139 dateTime.setTime_t( message->date() );
00140 dateString = locale->formatDateTime( dateTime );
00141 } else {
00142 dateString = message->dateStr();
00143 }
00144
00145 QString headerStr = "<div class=\"header\" dir=\"" + dir + "\">\n";
00146
00147 if ( strategy->showHeader( "subject" ) )
00148 headerStr += "<div dir=\"" + subjectDir + "\">\n"
00149 "<b style=\"font-size:130%\">" +
00150 strToHtml( message->subject() ) +
00151 "</b></div>\n";
00152
00153 QStringList headerParts;
00154
00155 if ( strategy->showHeader( "from" ) ) {
00156 QString fromPart = KMMessage::emailAddrAsAnchor( message->from(), true );
00157 if ( !vCardName.isEmpty() )
00158 fromPart += " <a href=\"" + vCardName + "\">" + i18n("[vCard]") + "</a>";
00159 headerParts << fromPart;
00160 }
00161
00162 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() )
00163 headerParts << i18n("CC: ") + KMMessage::emailAddrAsAnchor( message->cc(), true );
00164
00165 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() )
00166 headerParts << i18n("BCC: ") + KMMessage::emailAddrAsAnchor( message->bcc(), true );
00167
00168 if ( strategy->showHeader( "date" ) )
00169 headerParts << strToHtml(message->dateShortStr());
00170
00171
00172 headerStr += " (" + headerParts.grep( QRegExp( "\\S" ) ).join( ",\n" ) + ')';
00173
00174 headerStr += "</div>\n";
00175
00176
00177
00178 return headerStr;
00179 }
00180
00181
00182
00183
00184
00185
00186
00187 class PlainHeaderStyle : public HeaderStyle {
00188 friend class HeaderStyle;
00189 protected:
00190 PlainHeaderStyle() : HeaderStyle() {}
00191 virtual ~PlainHeaderStyle() {}
00192
00193 public:
00194 const char * name() const { return "plain"; }
00195 const HeaderStyle * next() const { return fancy(); }
00196 const HeaderStyle * prev() const { return brief(); }
00197
00198 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00199 const QString & vCardName, bool printing ) const;
00200
00201 private:
00202 QString formatAllMessageHeaders( const KMMessage * message ) const;
00203 };
00204
00205 QString PlainHeaderStyle::format( const KMMessage * message,
00206 const HeaderStrategy * strategy,
00207 const QString & vCardName, bool printing ) const {
00208 if ( !message ) return QString::null;
00209 if ( !strategy )
00210 strategy = HeaderStrategy::rich();
00211
00212
00213
00214
00215 QString dir = ( QApplication::reverseLayout() ? "rtl" : "ltr" );
00216
00217
00218
00219
00220
00221
00222
00223 QString subjectDir;
00224 if (!message->subject().isEmpty())
00225 subjectDir = directionOf( message->cleanSubject() );
00226 else
00227 subjectDir = directionOf( i18n("No Subject") );
00228
00229
00230 QString dateString;
00231 if( printing ) {
00232 QDateTime dateTime;
00233 KLocale* locale = KGlobal::locale();
00234 dateTime.setTime_t( message->date() );
00235 dateString = locale->formatDateTime( dateTime );
00236 }
00237 else {
00238 dateString = message->dateStr();
00239 }
00240
00241 QString headerStr = QString("<div class=\"header\" dir=\"%1\">").arg(dir);
00242
00243 if ( strategy->headersToDisplay().isEmpty()
00244 && strategy->defaultPolicy() == HeaderStrategy::Display ) {
00245
00246 headerStr += formatAllMessageHeaders( message );
00247 return headerStr + "</div>";
00248 }
00249
00250
00251 if ( strategy->showHeader( "subject" ) )
00252 headerStr += QString("<div dir=\"%1\"><b style=\"font-size:130%\">" +
00253 strToHtml(message->subject()) + "</b></div>\n")
00254 .arg(subjectDir);
00255
00256 if ( strategy->showHeader( "date" ) )
00257 headerStr.append(i18n("Date: ") + strToHtml(dateString)+"<br>\n");
00258
00259
00260 QString presence;
00261 QString kabcUid;
00262 if ( strategy->showHeader( "status" ) )
00263 {
00264 KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
00265 KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getEmailAddr( message->from() ) );
00266 ::KIMProxy *imProxy = KMKernel::self()->imProxy();
00267 kabcUid = addresses[0].uid();
00268 presence = imProxy->presenceString( kabcUid );
00269 }
00270
00271 if ( strategy->showHeader( "from" ) ) {
00272 headerStr.append(i18n("From: ") +
00273 KMMessage::emailAddrAsAnchor(message->from(),FALSE));
00274 if ( !vCardName.isEmpty() )
00275 headerStr.append(" <a href=\"" + vCardName +
00276 "\">" + i18n("[vCard]") + "</a>" );
00277 if ( !presence.isEmpty() && strategy->showHeader( "status" ) )
00278 headerStr.append(" (<span name=\"presence-" + kabcUid + "\">" + presence + "</span>)" );
00279 if ( strategy->showHeader( "organization" )
00280 && !message->headerField("Organization").isEmpty())
00281 headerStr.append(" (" +
00282 strToHtml(message->headerField("Organization")) + ")");
00283 headerStr.append("<br>\n");
00284 }
00285
00286 if ( strategy->showHeader( "to" ) )
00287 headerStr.append(i18n("To: ")+
00288 KMMessage::emailAddrAsAnchor(message->to(),FALSE) + "<br>\n");
00289
00290 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() )
00291 headerStr.append(i18n("CC: ")+
00292 KMMessage::emailAddrAsAnchor(message->cc(),FALSE) + "<br>\n");
00293
00294 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() )
00295 headerStr.append(i18n("BCC: ")+
00296 KMMessage::emailAddrAsAnchor(message->bcc(),FALSE) + "<br>\n");
00297
00298 if ( strategy->showHeader( "reply-to" ) && !message->replyTo().isEmpty())
00299 headerStr.append(i18n("Reply to: ")+
00300 KMMessage::emailAddrAsAnchor(message->replyTo(),FALSE) + "<br>\n");
00301
00302 headerStr += "</div>\n";
00303
00304 return headerStr;
00305 }
00306
00307 QString PlainHeaderStyle::formatAllMessageHeaders( const KMMessage * message ) const {
00308 const DwHeaders & headers = message->headers();
00309 QString result;
00310
00311 for ( const DwField * field = headers.FirstField() ; field ; field = field->Next() ) {
00312 result += ( field->FieldNameStr() + ": " ).c_str();
00313 result += strToHtml( field->FieldBodyStr().c_str() );
00314 result += "<br>\n";
00315 }
00316
00317 return result;
00318 }
00319
00320
00321
00322
00323
00324
00325 class FancyHeaderStyle : public HeaderStyle {
00326 friend class HeaderStyle;
00327 protected:
00328 FancyHeaderStyle() : HeaderStyle() {}
00329 virtual ~FancyHeaderStyle() {}
00330
00331 public:
00332 const char * name() const { return "fancy"; }
00333 const HeaderStyle * next() const { return brief(); }
00334 const HeaderStyle * prev() const { return plain(); }
00335
00336 QString format( const KMMessage * message, const HeaderStrategy * strategy,
00337 const QString & vCardName, bool printing ) const;
00338 static QString imgToDataUrl( const QImage &image );
00339
00340 };
00341
00342 QString FancyHeaderStyle::format( const KMMessage * message,
00343 const HeaderStrategy * strategy,
00344 const QString & vCardName, bool printing ) const {
00345 if ( !message ) return QString::null;
00346 if ( !strategy )
00347 strategy = HeaderStrategy::rich();
00348
00349
00350
00351
00352
00353 QString dir = ( QApplication::reverseLayout() ? "rtl" : "ltr" );
00354 QString headerStr = QString("<div class=\"fancy header\" dir=\"%1\">\n").arg(dir);
00355
00356
00357
00358
00359
00360
00361
00362 QString subjectDir;
00363 if ( !message->subject().isEmpty() )
00364 subjectDir = directionOf( message->cleanSubject() );
00365 else
00366 subjectDir = directionOf( i18n("No Subject") );
00367
00368
00369 QString dateString;
00370 if( printing ) {
00371 QDateTime dateTime;
00372 KLocale* locale = KGlobal::locale();
00373 dateTime.setTime_t( message->date() );
00374 dateString = locale->formatDateTime( dateTime );
00375 }
00376 else {
00377 dateString = message->dateStr();
00378 }
00379
00380 QString userHTML;
00381 QString presence;
00382
00383
00384
00385
00386 ::KIMProxy *imProxy = KMKernel::self()->imProxy();
00387 QString kabcUid;
00388 if ( ( strategy->showHeader( "status" ) || strategy->showHeader( "statuspic" ) ) )
00389 {
00390 if ( imProxy->initialize() )
00391 {
00392 KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
00393 KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getEmailAddr( message->from() ) );
00394
00395 if( addresses.count() == 1 )
00396 {
00397
00398 kabcUid = addresses[0].uid();
00399
00400
00401 presence = imProxy->presenceString( kabcUid );
00402 if ( !presence.isEmpty() )
00403 {
00404 QString presenceIcon = QString::fromLatin1( " <img src=\"%1\"/>" )
00405 .arg( imgToDataUrl( imProxy->presenceIcon( kabcUid ).convertToImage() ) );
00406 presence += presenceIcon;
00407 }
00408
00409 if ( strategy->showHeader( "statuspic" ) )
00410 {
00411 QString photoURL;
00412 if ( addresses[0].photo().isIntern() )
00413 {
00414
00415
00416 QImage photo = addresses[0].photo().data();
00417 if ( !photo.isNull() )
00418 {
00419 photoURL = imgToDataUrl( photo );
00420 }
00421 }
00422 else
00423 {
00424
00425 photoURL = addresses[0].photo().url();
00426 if ( photoURL.startsWith("/") )
00427 photoURL.prepend( "file:" );
00428 }
00429 if( !photoURL.isEmpty() )
00430 {
00431
00432 userHTML = QString("<img src=\"%1\" width=\"60\" height=\"60\">").arg( photoURL );
00433 if ( presence.isEmpty() )
00434 {
00435 userHTML = QString("<div class=\"senderpic\">") + userHTML + "</div>";
00436 }
00437 else
00438 userHTML = QString( "<div class=\"senderpic\">"
00439 "<a href=\"im:%1\">%2<div class=\"senderstatus\"><span name=\"presence-%2\">%3</span></div></a>"
00440 "</div>" ).arg( kabcUid )
00441 .arg( userHTML )
00442 .arg( presence );
00443 }
00444 }
00445 }
00446 else
00447 {
00448 kdDebug( 5006 ) << "Multiple / No addressees matched email address; Count is " << addresses.count() << endl;
00449 userHTML = " ";
00450 }
00451 }
00452
00453
00454
00455
00456 }
00457
00458
00459 kdDebug( 5006 ) << "final presence: '" << presence << "'" << endl;
00460
00461
00462 if ( strategy->showHeader( "subject" ) )
00463 headerStr += QString("<div dir=\"%1\">%2</div>\n")
00464 .arg(subjectDir)
00465 .arg(message->subject().isEmpty()?
00466 i18n("No Subject") :
00467 strToHtml(message->subject()));
00468 headerStr += "<table class=\"outer\"><tr><td width=\"100%\"><table>\n";
00469
00470
00471
00472
00473 if ( strategy->showHeader( "from" ) )
00474 headerStr += QString("<tr><th>%1</th>\n"
00475 "<td>")
00476 .arg(i18n("From: "))
00477 + KMMessage::emailAddrAsAnchor(message->from(),FALSE)
00478 + ( !vCardName.isEmpty() ? " <a href=\"" + vCardName + "\">"
00479 + i18n("[vCard]") + "</a>"
00480 : QString("") )
00481 + ( ( !presence.isEmpty() && strategy->showHeader( "status" ) )
00482 ? " (<span name=\"presence-" + kabcUid + "\">" + presence + "</span>)"
00483 : QString("") )
00484 + ( message->headerField("Organization").isEmpty()
00485 ? QString("")
00486 : " ("
00487 + strToHtml(message->headerField("Organization"))
00488 + ")")
00489 + "</td></tr>\n";
00490
00491 if ( strategy->showHeader( "to" ) )
00492 headerStr.append(QString("<tr><th>%1</th>\n"
00493 "<td>%2</td></tr>\n")
00494 .arg(i18n("To: "))
00495 .arg(KMMessage::emailAddrAsAnchor(message->to(),FALSE)));
00496
00497
00498 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty())
00499 headerStr.append(QString("<tr><th>%1</th>\n"
00500 "<td>%2</td></tr>\n")
00501 .arg(i18n("CC: "))
00502 .arg(KMMessage::emailAddrAsAnchor(message->cc(),FALSE)));
00503
00504
00505 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty())
00506 headerStr.append(QString("<tr><th>%1</th>\n"
00507 "<td>%2</td></tr>\n")
00508 .arg(i18n("BCC: "))
00509 .arg(KMMessage::emailAddrAsAnchor(message->bcc(),FALSE)));
00510
00511 if ( strategy->showHeader( "date" ) )
00512 headerStr.append(QString("<tr><th>%1</th>\n"
00513 "<td dir=\"%2\">%3</td></tr>\n")
00514 .arg(i18n("Date: "))
00515 .arg( directionOf( message->dateStr() ) )
00516 .arg(strToHtml(dateString)));
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 headerStr.append(
00527 QString("</table></td><td align=\"center\">%1</td></tr></table>\n").arg(userHTML)
00528 );
00529
00530 headerStr += "</div>\n\n";
00531 return headerStr;
00532 }
00533
00534 QString FancyHeaderStyle::imgToDataUrl( const QImage &image )
00535 {
00536 QByteArray ba;
00537 QBuffer buffer( ba );
00538 buffer.open( IO_WriteOnly );
00539 image.save( &buffer, "PNG" );
00540 return QString::fromLatin1("data:image/png;base64,%1").arg( KCodecs::base64Encode( ba ) );
00541 }
00542
00543
00544
00545
00546 HeaderStyle::HeaderStyle() {
00547
00548 }
00549
00550 HeaderStyle::~HeaderStyle() {
00551
00552 }
00553
00554 const HeaderStyle * HeaderStyle::create( Type type ) {
00555 switch ( type ) {
00556 case Brief: return brief();
00557 case Plain: return plain();
00558 case Fancy: return fancy();
00559 }
00560 kdFatal( 5006 ) << "HeaderStyle::create(): Unknown header style ( type == "
00561 << (int)type << " ) requested!" << endl;
00562 return 0;
00563 }
00564
00565 const HeaderStyle * HeaderStyle::create( const QString & type ) {
00566 QString lowerType = type.lower();
00567 if ( lowerType == "brief" ) return brief();
00568 if ( lowerType == "plain" ) return plain();
00569
00570
00571
00572 return fancy();
00573 }
00574
00575 static const HeaderStyle * briefStyle = 0;
00576 static const HeaderStyle * plainStyle = 0;
00577 static const HeaderStyle * fancyStyle = 0;
00578
00579 const HeaderStyle * HeaderStyle::brief() {
00580 if ( !briefStyle )
00581 briefStyle = new BriefHeaderStyle();
00582 return briefStyle;
00583 }
00584
00585 const HeaderStyle * HeaderStyle::plain() {
00586 if ( !plainStyle )
00587 plainStyle = new PlainHeaderStyle();
00588 return plainStyle;
00589 }
00590
00591 const HeaderStyle * HeaderStyle::fancy() {
00592 if ( !fancyStyle )
00593 fancyStyle = new FancyHeaderStyle();
00594 return fancyStyle;
00595 }
00596
00597 }
This file is part of the documentation for kmail Library Version 3.3.2.