akonadi
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( "<a href=\"address:?index=%1\">%2</a>" ).arg( counter).arg( formattedAddress ); 00136 counter++; 00137 00138 dynamicPart += rowFmtStr 00139 .arg( KABC::Address::typeLabel( address.type() ) ) 00140 .arg( url ); 00141 } 00142 00143 // Note 00144 QString notes; 00145 if ( !rawContact.note().isEmpty() ) 00146 notes = rowFmtStr.arg( i18n( "Notes" ) ).arg( rawContact.note().replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) ) ) ; 00147 00148 // Custom Data 00149 QString customData; 00150 static QMap<QString, QString> titleMap; 00151 if ( titleMap.isEmpty() ) { 00152 titleMap.insert( QLatin1String( "Department" ), i18n( "Department" ) ); 00153 titleMap.insert( QLatin1String( "Profession" ), i18n( "Profession" ) ); 00154 titleMap.insert( QLatin1String( "AssistantsName" ), i18n( "Assistant's Name" ) ); 00155 titleMap.insert( QLatin1String( "ManagersName" ), i18n( "Manager's Name" ) ); 00156 titleMap.insert( QLatin1String( "SpousesName" ), i18nc( "Wife/Husband/...", "Partner's Name" ) ); 00157 titleMap.insert( QLatin1String( "Office" ), i18n( "Office" ) ); 00158 titleMap.insert( QLatin1String( "IMAddress" ), i18n( "IM Address" ) ); 00159 titleMap.insert( QLatin1String( "Anniversary" ), i18n( "Anniversary" ) ); 00160 titleMap.insert( QLatin1String( "AddressBook" ), i18n( "Address Book" ) ); 00161 } 00162 00163 static QSet<QString> blacklistedKeys; 00164 if ( blacklistedKeys.isEmpty() ) { 00165 blacklistedKeys.insert( QLatin1String( "CRYPTOPROTOPREF" ) ); 00166 blacklistedKeys.insert( QLatin1String( "OPENPGPFP" ) ); 00167 blacklistedKeys.insert( QLatin1String( "SMIMEFP" ) ); 00168 blacklistedKeys.insert( QLatin1String( "CRYPTOSIGNPREF" ) ); 00169 blacklistedKeys.insert( QLatin1String( "CRYPTOENCRYPTPREF" ) ); 00170 } 00171 00172 if ( !rawContact.customs().empty() ) { 00173 const QStringList customs = rawContact.customs(); 00174 foreach ( QString custom, customs ) { //krazy:exclude=foreach 00175 if ( custom.startsWith( QLatin1String( "KADDRESSBOOK-" ) ) ) { 00176 custom.remove( QLatin1String( "KADDRESSBOOK-X-" ) ); 00177 custom.remove( QLatin1String( "KADDRESSBOOK-" ) ); 00178 00179 int pos = custom.indexOf( QLatin1Char( ':' ) ); 00180 QString key = custom.left( pos ); 00181 QString value = custom.mid( pos + 1 ); 00182 00183 // convert anniversary correctly 00184 if ( key == QLatin1String( "Anniversary" ) ) { 00185 const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate ); 00186 value = KGlobal::locale()->formatDate( dateTime.date() ); 00187 } 00188 00189 // blog is handled separated 00190 if ( key == QLatin1String( "BlogFeed" ) ) 00191 continue; 00192 00193 if ( blacklistedKeys.contains( key ) ) 00194 continue; 00195 00196 // check whether we have a mapping for the title 00197 const QMap<QString, QString>::ConstIterator keyIt = titleMap.constFind( key ); 00198 if ( keyIt != titleMap.constEnd() ) { 00199 key = keyIt.value(); 00200 } else { 00201 // check whether it is a custom local field 00202 foreach ( const QVariantMap &description, customFieldDescriptions() ) { 00203 if ( description.value( QLatin1String( "key" ) ).toString() == key ) { 00204 key = description.value( QLatin1String( "title" ) ).toString(); 00205 if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "boolean" ) ) { 00206 if ( value == QLatin1String( "true" ) ) 00207 value = i18nc( "Boolean value", "yes" ); 00208 else 00209 value = i18nc( "Boolean value", "no" ); 00210 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "date" ) ) { 00211 const QDate date = QDate::fromString( value, Qt::ISODate ); 00212 value = KGlobal::locale()->formatDate( date, KLocale::ShortDate ); 00213 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "time" ) ) { 00214 const QTime time = QTime::fromString( value, Qt::ISODate ); 00215 value = KGlobal::locale()->formatTime( time ); 00216 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "datetime" ) ) { 00217 const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate ); 00218 value = KGlobal::locale()->formatDateTime( dateTime, KLocale::ShortDate ); 00219 } 00220 break; 00221 } 00222 } 00223 } 00224 00225 customData += rowFmtStr.arg( key ).arg( value ) ; 00226 } 00227 } 00228 } 00229 00230 // Assemble all parts 00231 QString role = rawContact.title(); 00232 if ( role.isEmpty() ) 00233 role = rawContact.role(); 00234 if ( role.isEmpty() ) 00235 role = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ) ); 00236 00237 QString strAddr = QString::fromLatin1( 00238 "<div align=\"center\">" 00239 "<table cellpadding=\"3\" cellspacing=\"0\">" 00240 "<tr>" 00241 "<td align=\"right\" valign=\"top\" width=\"30%\" rowspan=\"3\">" 00242 "<img src=\"%1\" width=\"100\" vspace=\"1\">" // image 00243 "</td>" 00244 "<td align=\"left\" width=\"70%\"><font size=\"+2\"><b>%2</b></font></td>" // name 00245 "</tr>" 00246 "<tr>" 00247 "<td align=\"left\" width=\"70%\">%3</td>" // role 00248 "</tr>" 00249 "<tr>" 00250 "<td align=\"left\" width=\"70%\">%4</td>" // organization 00251 "</tr>") 00252 .arg( QLatin1String( "contact_photo" ) ) 00253 .arg( rawContact.realName() ) 00254 .arg( role ) 00255 .arg( rawContact.organization() ); 00256 00257 strAddr.append( dynamicPart ); 00258 strAddr.append( notes ); 00259 strAddr.append( customData ); 00260 strAddr.append( QString::fromLatin1( "</table></div>\n" ) ); 00261 00262 if ( form == EmbeddableForm ) 00263 return strAddr; 00264 00265 const QString document = QString::fromLatin1( 00266 "<html>" 00267 "<head>" 00268 " <style type=\"text/css\">" 00269 " a {text-decoration:none; color:%1}" 00270 " </style>" 00271 "</head>" 00272 "<body text=\"%1\" bgcolor=\"%2\">" // text and background color 00273 "%3" // contact part 00274 "</body>" 00275 "</html>" ) 00276 .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() ) 00277 .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() ) 00278 .arg( strAddr ); 00279 00280 return document; 00281 }