kmail Library API Documentation

headerstyle.cpp

00001 /* -*- c++ -*- 00002 headerstyle.cpp 00003 00004 This file is part of KMail, the KDE mail client. 00005 Copyright (c) 2003 Marc Mutz <mutz@kde.org> 00006 00007 KMail is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License, version 2, as 00009 published by the Free Software Foundation. 00010 00011 KMail is distributed in the hope that it will be useful, but 00012 WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 00020 In addition, as a special exception, the copyright holders give 00021 permission to link the code of this program with any edition of 00022 the Qt library by Trolltech AS, Norway (or with modified versions 00023 of Qt that use the same license as Qt), and distribute linked 00024 combinations including the two. You must obey the GNU General 00025 Public License in all respects for all of the code used other than 00026 Qt. If you modify this file, you may extend this exception to 00027 your version of the file, but you are not obligated to do so. If 00028 you do not wish to do so, delete this exception statement from 00029 your version. 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 00042 00043 #include <mimelib/string.h> 00044 #include <mimelib/field.h> 00045 #include <mimelib/headers.h> 00046 00047 #include <kdebug.h> 00048 #include <klocale.h> 00049 #include <kglobal.h> 00050 00051 #include <qdatetime.h> 00052 #include <qapplication.h> 00053 #include <qregexp.h> 00054 00055 namespace KMail { 00056 00057 // 00058 // Convenience functions: 00059 // 00060 static inline QString directionOf( const QString & str ) { 00061 return str.isRightToLeft() ? "rtl" : "ltr" ; 00062 } 00063 00064 #if 0 00065 // Converts to html. Changes URLs into href's, escapes HTML special 00066 // chars and inserts the result into an <div> or <span> tag with 00067 // "dir" set to "rtl" or "ltr" depending on the direction of @p str. 00068 static QString convertToHtmlBlock( const QString & str, bool useSpan=false ) { 00069 QString dir = directionOf( str ); 00070 QString format = "<%1 dir=\"%3\">%4</%2>"; 00071 return format.arg( useSpan ? "span" : "div" ) 00072 .arg( useSpan ? "span" : "div" ) 00073 .arg( dir ) 00074 .arg( LinkLocator::convertToHtml( str ) ); 00075 } 00076 #endif 00077 00078 // ### tmp wrapper to make kmreaderwin code working: 00079 static QString strToHtml( const QString & str, bool preserveBlanks=true ) { 00080 return LinkLocator::convertToHtml( str, preserveBlanks ); 00081 } 00082 00083 // 00084 // BriefHeaderStyle 00085 // Show everything in a single line, don't show header field names. 00086 // 00087 00088 class BriefHeaderStyle : public HeaderStyle { 00089 friend class HeaderStyle; 00090 protected: 00091 BriefHeaderStyle() : HeaderStyle() {} 00092 virtual ~BriefHeaderStyle() {} 00093 00094 public: 00095 const char * name() const { return "brief"; } 00096 const HeaderStyle * next() const { return plain(); } 00097 const HeaderStyle * prev() const { return fancy(); } 00098 00099 QString format( const KMMessage * message, const HeaderStrategy * strategy, 00100 const QString & vCardName, bool printing ) const; 00101 }; 00102 00103 QString BriefHeaderStyle::format( const KMMessage * message, 00104 const HeaderStrategy * strategy, 00105 const QString & vCardName, bool printing ) const { 00106 if ( !message ) return QString::null; 00107 if ( !strategy ) 00108 strategy = HeaderStrategy::brief(); 00109 00110 // The direction of the header is determined according to the direction 00111 // of the application layout. 00112 00113 QString dir = QApplication::reverseLayout() ? "rtl" : "ltr" ; 00114 00115 // However, the direction of the message subject within the header is 00116 // determined according to the contents of the subject itself. Since 00117 // the "Re:" and "Fwd:" prefixes would always cause the subject to be 00118 // considered left-to-right, they are ignored when determining its 00119 // direction. 00120 00121 QString subjectDir; 00122 if (!message->subject().isEmpty()) 00123 subjectDir = directionOf( message->cleanSubject() ); 00124 else 00125 subjectDir = directionOf( i18n("No Subject") ); 00126 00127 // Prepare the date string (when printing always use the localized date) 00128 QString dateString; 00129 if( printing ) { 00130 QDateTime dateTime; 00131 KLocale * locale = KGlobal::locale(); 00132 dateTime.setTime_t( message->date() ); 00133 dateString = locale->formatDateTime( dateTime ); 00134 } else { 00135 dateString = message->dateStr(); 00136 } 00137 00138 QString headerStr = "<div class=\"header\" dir=\"" + dir + "\">\n"; 00139 00140 if ( strategy->showHeader( "subject" ) ) 00141 headerStr += "<div dir=\"" + subjectDir + "\">\n" 00142 "<b style=\"font-size:130%\">" + 00143 strToHtml( message->subject() ) + 00144 "</b></div>\n"; 00145 00146 QStringList headerParts; 00147 00148 if ( strategy->showHeader( "from" ) ) { 00149 QString fromPart = KMMessage::emailAddrAsAnchor( message->from(), true ); 00150 if ( !vCardName.isEmpty() ) 00151 fromPart += "&nbsp;&nbsp;<a href=\"" + vCardName + "\">" + i18n("[vCard]") + "</a>"; 00152 headerParts << fromPart; 00153 } 00154 00155 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() ) 00156 headerParts << i18n("CC: ") + KMMessage::emailAddrAsAnchor( message->cc(), true ); 00157 00158 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() ) 00159 headerParts << i18n("BCC: ") + KMMessage::emailAddrAsAnchor( message->bcc(), true ); 00160 00161 if ( strategy->showHeader( "date" ) ) 00162 headerParts << strToHtml(message->dateShortStr()); 00163 00164 // remove all empty (modulo whitespace) entries and joins them via ", \n" 00165 headerStr += " (" + headerParts.grep( QRegExp( "\\S" ) ).join( ",\n" ) + ')'; 00166 00167 headerStr += "</div>\n"; 00168 00169 // ### iterate over the rest of strategy->headerToDisplay() (or 00170 // ### all headers if DefaultPolicy == Display) (elsewhere, too) 00171 return headerStr; 00172 } 00173 00174 // 00175 // PlainHeaderStyle: 00176 // show every header field on a line by itself, 00177 // show subject larger 00178 // 00179 00180 class PlainHeaderStyle : public HeaderStyle { 00181 friend class HeaderStyle; 00182 protected: 00183 PlainHeaderStyle() : HeaderStyle() {} 00184 virtual ~PlainHeaderStyle() {} 00185 00186 public: 00187 const char * name() const { return "plain"; } 00188 const HeaderStyle * next() const { return fancy(); } 00189 const HeaderStyle * prev() const { return brief(); } 00190 00191 QString format( const KMMessage * message, const HeaderStrategy * strategy, 00192 const QString & vCardName, bool printing ) const; 00193 00194 private: 00195 QString formatAllMessageHeaders( const KMMessage * message ) const; 00196 }; 00197 00198 QString PlainHeaderStyle::format( const KMMessage * message, 00199 const HeaderStrategy * strategy, 00200 const QString & vCardName, bool printing ) const { 00201 if ( !message ) return QString::null; 00202 if ( !strategy ) 00203 strategy = HeaderStrategy::rich(); 00204 00205 // The direction of the header is determined according to the direction 00206 // of the application layout. 00207 00208 QString dir = ( QApplication::reverseLayout() ? "rtl" : "ltr" ); 00209 00210 // However, the direction of the message subject within the header is 00211 // determined according to the contents of the subject itself. Since 00212 // the "Re:" and "Fwd:" prefixes would always cause the subject to be 00213 // considered left-to-right, they are ignored when determining its 00214 // direction. 00215 00216 QString subjectDir; 00217 if (!message->subject().isEmpty()) 00218 subjectDir = directionOf( message->cleanSubject() ); 00219 else 00220 subjectDir = directionOf( i18n("No Subject") ); 00221 00222 // Prepare the date string (when printing always use the localized date) 00223 QString dateString; 00224 if( printing ) { 00225 QDateTime dateTime; 00226 KLocale* locale = KGlobal::locale(); 00227 dateTime.setTime_t( message->date() ); 00228 dateString = locale->formatDateTime( dateTime ); 00229 } 00230 else { 00231 dateString = message->dateStr(); 00232 } 00233 00234 QString headerStr = QString("<div class=\"header\" dir=\"%1\">").arg(dir); 00235 00236 if ( strategy->headersToDisplay().isEmpty() 00237 && strategy->defaultPolicy() == HeaderStrategy::Display ) { 00238 // crude way to emulate "all" headers: 00239 headerStr += formatAllMessageHeaders( message ); 00240 return headerStr + "</div>"; 00241 } 00242 00243 //case HdrLong: 00244 if ( strategy->showHeader( "subject" ) ) 00245 headerStr += QString("<div dir=\"%1\"><b style=\"font-size:130%\">" + 00246 strToHtml(message->subject()) + "</b></div>\n") 00247 .arg(subjectDir); 00248 00249 if ( strategy->showHeader( "date" ) ) 00250 headerStr.append(i18n("Date: ") + strToHtml(dateString)+"<br>\n"); 00251 00252 if ( strategy->showHeader( "from" ) ) { 00253 headerStr.append(i18n("From: ") + 00254 KMMessage::emailAddrAsAnchor(message->from(),FALSE)); 00255 if ( !vCardName.isEmpty() ) 00256 headerStr.append("&nbsp;&nbsp;<a href=\"" + vCardName + 00257 "\">" + i18n("[vCard]") + "</a>" ); 00258 if ( strategy->showHeader( "organization" ) 00259 && !message->headerField("Organization").isEmpty()) 00260 headerStr.append("&nbsp;&nbsp;(" + 00261 strToHtml(message->headerField("Organization")) + ")"); 00262 headerStr.append("<br>\n"); 00263 } 00264 00265 if ( strategy->showHeader( "to" ) ) 00266 headerStr.append(i18n("To: ")+ 00267 KMMessage::emailAddrAsAnchor(message->to(),FALSE) + "<br>\n"); 00268 00269 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty() ) 00270 headerStr.append(i18n("CC: ")+ 00271 KMMessage::emailAddrAsAnchor(message->cc(),FALSE) + "<br>\n"); 00272 00273 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty() ) 00274 headerStr.append(i18n("BCC: ")+ 00275 KMMessage::emailAddrAsAnchor(message->bcc(),FALSE) + "<br>\n"); 00276 00277 if ( strategy->showHeader( "reply-to" ) && !message->replyTo().isEmpty()) 00278 headerStr.append(i18n("Reply to: ")+ 00279 KMMessage::emailAddrAsAnchor(message->replyTo(),FALSE) + "<br>\n"); 00280 00281 headerStr += "</div>\n"; 00282 00283 return headerStr; 00284 } 00285 00286 QString PlainHeaderStyle::formatAllMessageHeaders( const KMMessage * message ) const { 00287 const DwHeaders & headers = message->headers(); 00288 QString result; 00289 00290 for ( const DwField * field = headers.FirstField() ; field ; field = field->Next() ) { 00291 result += ( field->FieldNameStr() + ": " ).c_str(); 00292 result += strToHtml( field->FieldBodyStr().c_str() ); 00293 result += "<br>\n"; 00294 } 00295 00296 return result; 00297 } 00298 00299 // 00300 // FancyHeaderStyle: 00301 // Like PlainHeaderStyle, but with slick frames and background colours. 00302 // 00303 00304 class FancyHeaderStyle : public HeaderStyle { 00305 friend class HeaderStyle; 00306 protected: 00307 FancyHeaderStyle() : HeaderStyle() {} 00308 virtual ~FancyHeaderStyle() {} 00309 00310 public: 00311 const char * name() const { return "fancy"; } 00312 const HeaderStyle * next() const { return brief(); } 00313 const HeaderStyle * prev() const { return plain(); } 00314 00315 QString format( const KMMessage * message, const HeaderStrategy * strategy, 00316 const QString & vCardName, bool printing ) const; 00317 }; 00318 00319 QString FancyHeaderStyle::format( const KMMessage * message, 00320 const HeaderStrategy * strategy, 00321 const QString & vCardName, bool printing ) const { 00322 if ( !message ) return QString::null; 00323 if ( !strategy ) 00324 strategy = HeaderStrategy::rich(); 00325 00326 // ### from kmreaderwin begin 00327 // The direction of the header is determined according to the direction 00328 // of the application layout. 00329 00330 QString dir = ( QApplication::reverseLayout() ? "rtl" : "ltr" ); 00331 QString headerStr = QString("<div class=\"fancy header\" dir=\"%1\">\n").arg(dir); 00332 00333 // However, the direction of the message subject within the header is 00334 // determined according to the contents of the subject itself. Since 00335 // the "Re:" and "Fwd:" prefixes would always cause the subject to be 00336 // considered left-to-right, they are ignored when determining its 00337 // direction. 00338 00339 QString subjectDir; 00340 if ( !message->subject().isEmpty() ) 00341 subjectDir = directionOf( message->cleanSubject() ); 00342 else 00343 subjectDir = directionOf( i18n("No Subject") ); 00344 00345 // Prepare the date string (when printing always use the localized date) 00346 QString dateString; 00347 if( printing ) { 00348 QDateTime dateTime; 00349 KLocale* locale = KGlobal::locale(); 00350 dateTime.setTime_t( message->date() ); 00351 dateString = locale->formatDateTime( dateTime ); 00352 } 00353 else { 00354 dateString = message->dateStr(); 00355 } 00356 00357 //case HdrFancy: 00358 // the subject line and box below for details 00359 if ( strategy->showHeader( "subject" ) ) 00360 headerStr += QString("<div dir=\"%1\">%2</div>\n") 00361 .arg(subjectDir) 00362 .arg(message->subject().isEmpty()? 00363 i18n("No Subject") : 00364 strToHtml(message->subject())); 00365 headerStr += "<table>\n"; 00366 00367 // from line 00368 // the mailto: URLs can contain %3 etc., therefore usage of multiple 00369 // QString::arg is not possible 00370 if ( strategy->showHeader( "from" ) ) 00371 headerStr += QString("<tr><th>%1</th>\n" 00372 "<td>") 00373 .arg(i18n("From: ")) 00374 + KMMessage::emailAddrAsAnchor(message->from(),FALSE) 00375 + ( !vCardName.isEmpty() ? "&nbsp;&nbsp;<a href=\"" + vCardName + "\">" 00376 + i18n("[vCard]") + "</a>" 00377 : QString("") ) 00378 + ( message->headerField("Organization").isEmpty() 00379 ? QString("") 00380 : "&nbsp;&nbsp;(" 00381 + strToHtml(message->headerField("Organization")) 00382 + ")") 00383 + "</td></tr>\n"; 00384 // to line 00385 if ( strategy->showHeader( "to" ) ) 00386 headerStr.append(QString("<tr><th>%1</th>\n" 00387 "<td>%2</td></tr>\n") 00388 .arg(i18n("To: ")) 00389 .arg(KMMessage::emailAddrAsAnchor(message->to(),FALSE))); 00390 00391 // cc line, if any 00392 if ( strategy->showHeader( "cc" ) && !message->cc().isEmpty()) 00393 headerStr.append(QString("<tr><th>%1</th>\n" 00394 "<td>%2</td></tr>\n") 00395 .arg(i18n("CC: ")) 00396 .arg(KMMessage::emailAddrAsAnchor(message->cc(),FALSE))); 00397 00398 // Bcc line, if any 00399 if ( strategy->showHeader( "bcc" ) && !message->bcc().isEmpty()) 00400 headerStr.append(QString("<tr><th>%1</th>\n" 00401 "<td>%2</td></tr>\n") 00402 .arg(i18n("BCC: ")) 00403 .arg(KMMessage::emailAddrAsAnchor(message->bcc(),FALSE))); 00404 00405 if ( strategy->showHeader( "date" ) ) 00406 headerStr.append(QString("<tr><th>%1</th>\n" 00407 "<td dir=\"%2\">%3</td></tr>\n") 00408 .arg(i18n("Date: ")) 00409 .arg( directionOf( message->dateStr() ) ) 00410 .arg(strToHtml(dateString))); 00411 headerStr.append("</table>\n"); 00412 00413 headerStr += "</div>\n\n"; 00414 00415 return headerStr; 00416 } 00417 00418 // 00419 // HeaderStyle abstract base: 00420 // 00421 00422 HeaderStyle::HeaderStyle() { 00423 00424 } 00425 00426 HeaderStyle::~HeaderStyle() { 00427 00428 } 00429 00430 const HeaderStyle * HeaderStyle::create( Type type ) { 00431 switch ( type ) { 00432 case Brief: return brief(); 00433 case Plain: return plain(); 00434 case Fancy: return fancy(); 00435 } 00436 kdFatal( 5006 ) << "HeaderStyle::create(): Unknown header style ( type == " 00437 << (int)type << " ) requested!" << endl; 00438 return 0; // make compiler happy 00439 } 00440 00441 const HeaderStyle * HeaderStyle::create( const QString & type ) { 00442 QString lowerType = type.lower(); 00443 if ( lowerType == "brief" ) return brief(); 00444 if ( lowerType == "plain" ) return plain(); 00445 //if ( lowerType == "fancy" ) return fancy(); // not needed, see below 00446 // don't kdFatal here, b/c the strings are user-provided 00447 // (KConfig), so fail gracefully to the default: 00448 return fancy(); 00449 } 00450 00451 static const HeaderStyle * briefStyle = 0; 00452 static const HeaderStyle * plainStyle = 0; 00453 static const HeaderStyle * fancyStyle = 0; 00454 00455 const HeaderStyle * HeaderStyle::brief() { 00456 if ( !briefStyle ) 00457 briefStyle = new BriefHeaderStyle(); 00458 return briefStyle; 00459 } 00460 00461 const HeaderStyle * HeaderStyle::plain() { 00462 if ( !plainStyle ) 00463 plainStyle = new PlainHeaderStyle(); 00464 return plainStyle; 00465 } 00466 00467 const HeaderStyle * HeaderStyle::fancy() { 00468 if ( !fancyStyle ) 00469 fancyStyle = new FancyHeaderStyle(); 00470 return fancyStyle; 00471 } 00472 00473 } // namespace KMail
KDE Logo
This file is part of the documentation for kmail Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:58 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003