akonadi/contact
standardcontactformatter.cpp
00001 /* 00002 This file is part of Akonadi Contact. 00003 00004 Copyright (c) 2010 Tobias Koenig <tokoe@kde.org> 00005 00006 This library is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU Library General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or (at your 00009 option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, but WITHOUT 00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to the 00018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00019 02110-1301, USA. 00020 */ 00021 00022 #include "standardcontactformatter.h" 00023 00024 #include <akonadi/item.h> 00025 #include <kabc/addressee.h> 00026 #include <kcolorscheme.h> 00027 #include <kglobal.h> 00028 #include <klocale.h> 00029 #include <kstringhandler.h> 00030 00031 #include <QtCore/QSet> 00032 00033 using namespace Akonadi; 00034 00035 StandardContactFormatter::StandardContactFormatter() 00036 : d( 0 ) 00037 { 00038 } 00039 00040 StandardContactFormatter::~StandardContactFormatter() 00041 { 00042 } 00043 00044 QString StandardContactFormatter::toHtml( HtmlForm form ) const 00045 { 00046 KABC::Addressee rawContact; 00047 const Akonadi::Item localItem = item(); 00048 if ( localItem.isValid() && localItem.hasPayload<KABC::Addressee>() ) 00049 rawContact = localItem.payload<KABC::Addressee>(); 00050 else 00051 rawContact = contact(); 00052 00053 if ( rawContact.isEmpty() ) 00054 return QString(); 00055 00056 // We'll be building a table to display the vCard in. 00057 // Each row of the table will be built using this string for its HTML. 00058 00059 QString rowFmtStr = QString::fromLatin1( 00060 "<tr>" 00061 "<td align=\"right\" valign=\"top\" width=\"30%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>\n" 00062 "<td align=\"left\" valign=\"top\" width=\"70%\"><font size=\"-1\">%2</font></td>\n" 00063 "</tr>\n" 00064 ); 00065 00066 // Build the table's rows here 00067 QString dynamicPart; 00068 00069 // Birthday 00070 const QDate date = rawContact.birthday().date(); 00071 const int years = (date.daysTo( QDate::currentDate() ) / 365); 00072 00073 if ( date.isValid() ) 00074 dynamicPart += rowFmtStr 00075 .arg( KABC::Addressee::birthdayLabel() ) 00076 .arg( KGlobal::locale()->formatDate( date ) + 00077 QLatin1String( " " ) + i18np( "(One year old)", "(%1 years old)", years ) ); 00078 00079 // Phone Numbers 00080 int counter = 0; 00081 foreach ( const KABC::PhoneNumber &number, rawContact.phoneNumbers() ) { 00082 00083 QString url; 00084 if ( number.type() & KABC::PhoneNumber::Cell ) 00085 url = QString::fromLatin1( "<a href=\"phone:?index=%1\">%2</a> (<a href=\"sms:?index=%1\">SMS</a>)" ).arg( counter ).arg( number.number() ); 00086 else 00087 url = QString::fromLatin1( "<a href=\"phone:?index=%1\">%2</a>" ).arg( counter ).arg( number.number() ); 00088 00089 counter++; 00090 00091 dynamicPart += rowFmtStr 00092 .arg( number.typeLabel().replace( QLatin1String( " " ), QLatin1String( " " ) ) ) 00093 .arg( url ); 00094 } 00095 00096 // EMails 00097 foreach ( const QString &email, rawContact.emails() ) { 00098 QString type = i18nc( "a contact's email address", "Email" ); 00099 00100 const QString fullEmail = QString::fromLatin1( KUrl::toPercentEncoding( rawContact.fullEmail( email ) ) ); 00101 00102 dynamicPart += rowFmtStr.arg( type ) 00103 .arg( QString::fromLatin1( "<a href=\"mailto:%1\">%2</a>" ) 00104 .arg( fullEmail, email ) ); 00105 } 00106 00107 // Homepage 00108 if ( rawContact.url().isValid() ) { 00109 QString url = rawContact.url().url(); 00110 if ( !url.startsWith( QLatin1String( "http://" ) ) && !url.startsWith( QLatin1String( "https://" ) ) ) 00111 url = QLatin1String( "http://" ) + url; 00112 00113 url = KStringHandler::tagUrls( url ); 00114 dynamicPart += rowFmtStr.arg( i18n( "Homepage" ) ).arg( url ); 00115 } 00116 00117 // Blog Feed 00118 const QString blog = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "BlogFeed" ) ); 00119 if ( !blog.isEmpty() ) 00120 dynamicPart += rowFmtStr.arg( i18n( "Blog Feed" ) ).arg( KStringHandler::tagUrls( blog ) ); 00121 00122 // Addresses 00123 counter = 0; 00124 foreach ( const KABC::Address &address, rawContact.addresses() ) { 00125 QString formattedAddress; 00126 00127 if ( address.label().isEmpty() ) { 00128 formattedAddress = address.formattedAddress().trimmed(); 00129 } else { 00130 formattedAddress = address.label(); 00131 } 00132 00133 formattedAddress = formattedAddress.replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) ); 00134 00135 const QString url = QString::fromLatin1( "%1 <a href=\"address:?index=%2\"><img src=\"map_icon\" alt=\"%3\"/></a>" ) 00136 .arg( formattedAddress ) 00137 .arg( counter ) 00138 .arg( i18n( "Show address on map" ) ); 00139 counter++; 00140 00141 dynamicPart += rowFmtStr 00142 .arg( KABC::Address::typeLabel( address.type() ) ) 00143 .arg( url ); 00144 } 00145 00146 // Note 00147 QString notes; 00148 if ( !rawContact.note().isEmpty() ) 00149 notes = rowFmtStr.arg( i18n( "Notes" ) ).arg( rawContact.note().replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) ) ) ; 00150 00151 // Custom Data 00152 QString customData; 00153 static QMap<QString, QString> titleMap; 00154 if ( titleMap.isEmpty() ) { 00155 titleMap.insert( QLatin1String( "Department" ), i18n( "Department" ) ); 00156 titleMap.insert( QLatin1String( "Profession" ), i18n( "Profession" ) ); 00157 titleMap.insert( QLatin1String( "AssistantsName" ), i18n( "Assistant's Name" ) ); 00158 titleMap.insert( QLatin1String( "ManagersName" ), i18n( "Manager's Name" ) ); 00159 titleMap.insert( QLatin1String( "SpousesName" ), i18nc( "Wife/Husband/...", "Partner's Name" ) ); 00160 titleMap.insert( QLatin1String( "Office" ), i18n( "Office" ) ); 00161 titleMap.insert( QLatin1String( "IMAddress" ), i18n( "IM Address" ) ); 00162 titleMap.insert( QLatin1String( "Anniversary" ), i18n( "Anniversary" ) ); 00163 titleMap.insert( QLatin1String( "AddressBook" ), i18n( "Address Book" ) ); 00164 } 00165 00166 static QSet<QString> blacklistedKeys; 00167 if ( blacklistedKeys.isEmpty() ) { 00168 blacklistedKeys.insert( QLatin1String( "CRYPTOPROTOPREF" ) ); 00169 blacklistedKeys.insert( QLatin1String( "OPENPGPFP" ) ); 00170 blacklistedKeys.insert( QLatin1String( "SMIMEFP" ) ); 00171 blacklistedKeys.insert( QLatin1String( "CRYPTOSIGNPREF" ) ); 00172 blacklistedKeys.insert( QLatin1String( "CRYPTOENCRYPTPREF" ) ); 00173 } 00174 00175 if ( !rawContact.customs().empty() ) { 00176 const QStringList customs = rawContact.customs(); 00177 foreach ( QString custom, customs ) { //krazy:exclude=foreach 00178 if ( custom.startsWith( QLatin1String( "KADDRESSBOOK-" ) ) ) { 00179 custom.remove( QLatin1String( "KADDRESSBOOK-X-" ) ); 00180 custom.remove( QLatin1String( "KADDRESSBOOK-" ) ); 00181 00182 int pos = custom.indexOf( QLatin1Char( ':' ) ); 00183 QString key = custom.left( pos ); 00184 QString value = custom.mid( pos + 1 ); 00185 00186 // convert anniversary correctly 00187 if ( key == QLatin1String( "Anniversary" ) ) { 00188 const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate ); 00189 value = KGlobal::locale()->formatDate( dateTime.date() ); 00190 } 00191 00192 // blog is handled separated 00193 if ( key == QLatin1String( "BlogFeed" ) ) 00194 continue; 00195 00196 if ( blacklistedKeys.contains( key ) ) 00197 continue; 00198 00199 // check whether we have a mapping for the title 00200 const QMap<QString, QString>::ConstIterator keyIt = titleMap.constFind( key ); 00201 if ( keyIt != titleMap.constEnd() ) { 00202 key = keyIt.value(); 00203 } else { 00204 // check whether it is a custom local field 00205 foreach ( const QVariantMap &description, customFieldDescriptions() ) { 00206 if ( description.value( QLatin1String( "key" ) ).toString() == key ) { 00207 key = description.value( QLatin1String( "title" ) ).toString(); 00208 if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "boolean" ) ) { 00209 if ( value == QLatin1String( "true" ) ) 00210 value = i18nc( "Boolean value", "yes" ); 00211 else 00212 value = i18nc( "Boolean value", "no" ); 00213 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "date" ) ) { 00214 const QDate date = QDate::fromString( value, Qt::ISODate ); 00215 value = KGlobal::locale()->formatDate( date, KLocale::ShortDate ); 00216 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "time" ) ) { 00217 const QTime time = QTime::fromString( value, Qt::ISODate ); 00218 value = KGlobal::locale()->formatTime( time ); 00219 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "datetime" ) ) { 00220 const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate ); 00221 value = KGlobal::locale()->formatDateTime( dateTime, KLocale::ShortDate ); 00222 } 00223 break; 00224 } 00225 } 00226 } 00227 00228 customData += rowFmtStr.arg( key ).arg( value ) ; 00229 } 00230 } 00231 } 00232 00233 // Assemble all parts 00234 QString role = rawContact.title(); 00235 if ( role.isEmpty() ) 00236 role = rawContact.role(); 00237 if ( role.isEmpty() ) 00238 role = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ) ); 00239 00240 QString strAddr = QString::fromLatin1( 00241 "<div align=\"center\">" 00242 "<table cellpadding=\"3\" cellspacing=\"0\">" 00243 "<tr>" 00244 "<td align=\"right\" valign=\"top\" width=\"30%\" rowspan=\"3\">" 00245 "<img src=\"%1\" width=\"100\" vspace=\"1\">" // image 00246 "</td>" 00247 "<td align=\"left\" width=\"70%\"><font size=\"+2\"><b>%2</b></font></td>" // name 00248 "</tr>" 00249 "<tr>" 00250 "<td align=\"left\" width=\"70%\">%3</td>" // role 00251 "</tr>" 00252 "<tr>" 00253 "<td align=\"left\" width=\"70%\">%4</td>" // organization 00254 "</tr>") 00255 .arg( QLatin1String( "contact_photo" ) ) 00256 .arg( rawContact.realName() ) 00257 .arg( role ) 00258 .arg( rawContact.organization() ); 00259 00260 strAddr.append( dynamicPart ); 00261 strAddr.append( notes ); 00262 strAddr.append( customData ); 00263 strAddr.append( QString::fromLatin1( "</table>" ) ); 00264 00265 #ifdef HAVE_PRISON 00266 strAddr.append( QString::fromLatin1( 00267 "<p align=\"center\">" 00268 "<img src=\"%1\" vspace=\"1\">" 00269 "<img src=\"%2\" vspace=\"1\">" 00270 "</p>" 00271 ) 00272 .arg( QLatin1String( "datamatrix" ) ) 00273 .arg( QLatin1String( "qrcode" ) ) ); 00274 #endif // HAVE_PRISON 00275 00276 strAddr.append( QString::fromLatin1( "</div>\n" ) ); 00277 00278 if ( form == EmbeddableForm ) 00279 return strAddr; 00280 00281 const QString document = QString::fromLatin1( 00282 "<html>" 00283 "<head>" 00284 " <style type=\"text/css\">" 00285 " a {text-decoration:none; color:%1}" 00286 " </style>" 00287 "</head>" 00288 "<body text=\"%1\" bgcolor=\"%2\">" // text and background color 00289 "%3" // contact part 00290 "</body>" 00291 "</html>" ) 00292 .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() ) 00293 .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() ) 00294 .arg( strAddr ); 00295 00296 return document; 00297 }