Make me trust this output by using the original enums.
[kdepim.git] / kaddressbook / grantleecontactformatter.cpp
blobdf0776d537dd32842211bd0ca7c4f23144e2f5cb
1 /*
2 This file is part of Akonadi Contact.
4 Copyright (c) 2010 Tobias Koenig <tokoe@kde.org>
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Library General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
11 This library is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
22 #include "grantleecontactformatter.h"
24 #include <grantlee/context.h>
25 #include <grantlee/engine.h>
26 #include <grantlee/templateloader.h>
28 #include <akonadi/item.h>
29 #include <kabc/addressee.h>
30 #include <kcolorscheme.h>
31 #include <kglobal.h>
32 #include <klocale.h>
33 #include <kstringhandler.h>
35 #include <QtCore/QSet>
36 #include <QtCore/QRegExp>
38 using namespace Akonadi;
40 class GrantleeContactFormatter::Private
42 public:
43 Private( const QString &templatePath )
45 mEngine = new Grantlee::Engine;
47 mTemplateLoader = Grantlee::FileSystemTemplateLoader::Ptr( new Grantlee::FileSystemTemplateLoader );
48 mTemplateLoader->setTemplateDirs( QStringList() << templatePath );
49 mTemplateLoader->setTheme( QLatin1String( "default" ) );
51 mEngine->addTemplateLoader( mTemplateLoader );
52 mSelfcontainedTemplate = mEngine->loadByName( "contact.html" );
53 if ( mSelfcontainedTemplate->error() )
54 mErrorMessage += mSelfcontainedTemplate->errorString();
56 mEmbeddableTemplate = mEngine->loadByName( "contact_embedded.html" );
57 if ( mEmbeddableTemplate->error() )
58 mErrorMessage += mEmbeddableTemplate->errorString();
61 ~Private()
63 delete mEngine;
66 QVector<QObject*> mObjects;
67 Grantlee::Engine *mEngine;
68 Grantlee::FileSystemTemplateLoader::Ptr mTemplateLoader;
69 Grantlee::Template mSelfcontainedTemplate;
70 Grantlee::Template mEmbeddableTemplate;
71 QString mErrorMessage;
74 GrantleeContactFormatter::GrantleeContactFormatter( const QString &templatePath )
75 : d( new Private( templatePath ) )
79 GrantleeContactFormatter::~GrantleeContactFormatter()
81 delete d;
84 inline static void setHashField( QVariantHash &hash, const QString &name, const QString &value )
86 if ( !value.isEmpty() )
87 hash.insert( name, value );
90 static QVariantHash phoneNumberHash( const KABC::PhoneNumber &phoneNumber, int counter )
92 QVariantHash numberObject;
94 setHashField( numberObject, QLatin1String( "type" ), phoneNumber.typeLabel() );
95 setHashField( numberObject, QLatin1String( "number" ), phoneNumber.number() );
97 if ( !phoneNumber.isEmpty() ) {
98 const QString url = QString::fromLatin1( "<a href=\"phone:?index=%1\">%2</a>" ).arg( counter ).arg( phoneNumber.number() );
99 numberObject.insert( QLatin1String( "numberLink" ), url );
101 if ( phoneNumber.type() & KABC::PhoneNumber::Cell ) {
102 const QString url = QString::fromLatin1( "<a href=\"sms:?index=%1\">(SMS)</a>" ).arg( counter );
103 numberObject.insert( QLatin1String( "smsLink" ), url );
107 return numberObject;
110 static QVariantHash addressHash( const KABC::Address &address, int counter )
112 QVariantHash addressObject;
114 setHashField( addressObject, QLatin1String( "type" ), KABC::Address::typeLabel( address.type() ) );
115 setHashField( addressObject, QLatin1String( "street" ), address.street() );
116 setHashField( addressObject, QLatin1String( "postOfficeBox" ), address.postOfficeBox() );
117 setHashField( addressObject, QLatin1String( "locality" ), address.locality() );
118 setHashField( addressObject, QLatin1String( "region" ), address.region() );
119 setHashField( addressObject, QLatin1String( "postalCode" ), address.postalCode() );
120 setHashField( addressObject, QLatin1String( "country" ), address.country() );
121 setHashField( addressObject, QLatin1String( "label" ), address.label() );
122 setHashField( addressObject, QLatin1String( "formattedAddress" ), address.formattedAddress() );
124 QString formattedAddress;
126 if ( address.label().isEmpty() ) {
127 formattedAddress = address.formattedAddress().trimmed();
128 } else {
129 formattedAddress = address.label();
132 if ( !formattedAddress.isEmpty() ) {
133 formattedAddress = formattedAddress.replace( QRegExp( "\n+" ), QLatin1String( "<br/>" ) );
135 const QString url = QString::fromLatin1( "<a href=\"address:?index=%1\">%2</a>" ).arg( counter).arg( formattedAddress );
136 addressObject.insert( "formattedAddressLink", url );
139 return addressObject;
142 QString GrantleeContactFormatter::toHtml( HtmlForm form ) const
144 if ( !d->mErrorMessage.isEmpty() )
145 return d->mErrorMessage;
147 KABC::Addressee rawContact;
148 const Akonadi::Item localItem = item();
149 if ( localItem.isValid() && localItem.hasPayload<KABC::Addressee>() )
150 rawContact = localItem.payload<KABC::Addressee>();
151 else
152 rawContact = contact();
154 if ( rawContact.isEmpty() )
155 return QString();
157 QVariantHash contactObject;
159 // Name parts
160 setHashField( contactObject, QLatin1String( "name" ), rawContact.realName() );
161 setHashField( contactObject, QLatin1String( "formattedName" ), rawContact.formattedName() );
162 setHashField( contactObject, QLatin1String( "prefix" ), rawContact.prefix() );
163 setHashField( contactObject, QLatin1String( "givenName" ), rawContact.givenName() );
164 setHashField( contactObject, QLatin1String( "additionalName" ), rawContact.additionalName() );
165 setHashField( contactObject, QLatin1String( "familyName" ), rawContact.familyName() );
166 setHashField( contactObject, QLatin1String( "suffix" ), rawContact.suffix() );
167 setHashField( contactObject, QLatin1String( "nickName" ), rawContact.nickName() );
169 // Dates
170 const QDate birthday = rawContact.birthday().date();
171 if ( birthday.isValid() ) {
172 contactObject.insert( QLatin1String( "birthday" ), KGlobal::locale()->formatDate( birthday ) );
174 const int years = (birthday.daysTo( QDate::currentDate() ) / 365);
175 contactObject.insert( QLatin1String( "age" ), QString::number( years ) );
178 const QDate anniversary = QDate::fromString( rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Anniversary" ) ), Qt::ISODate );
179 if ( anniversary.isValid() ) {
180 contactObject.insert( QLatin1String( "anniversary" ), KGlobal::locale()->formatDate( anniversary ) );
183 // Emails
184 contactObject.insert( QLatin1String( "emails" ), rawContact.emails() );
186 // Phone numbers
187 QVariantList phoneNumbers;
188 int counter = 0;
189 foreach ( const KABC::PhoneNumber &phoneNumber, rawContact.phoneNumbers() ) {
190 phoneNumbers.append( phoneNumberHash( phoneNumber, counter ) );
191 counter++;
194 contactObject.insert( QLatin1String( "phoneNumbers" ), phoneNumbers );
196 // Homepage
197 if ( rawContact.url().isValid() ) {
198 QString url = rawContact.url().url();
199 if ( !url.startsWith( QLatin1String( "http://" ) ) && !url.startsWith( QLatin1String( "https://" ) ) )
200 url = QLatin1String( "http://" ) + url;
202 url = KStringHandler::tagUrls( url );
203 contactObject.insert( QLatin1String( "website" ), url );
206 // Blog Feed
207 const QString blog = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "BlogFeed" ) );
208 if ( !blog.isEmpty() ) {
209 contactObject.insert( QLatin1String( "blogUrl" ), KStringHandler::tagUrls( blog ) );
212 // Address Book
213 const QString addressBookName = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "AddressBook" ) );
214 if ( !addressBookName.isEmpty() ) {
215 contactObject.insert( QLatin1String( "addressBookName" ), addressBookName );
218 // Addresses
219 QVariantList addresses;
220 counter = 0;
221 foreach ( const KABC::Address &address, rawContact.addresses() ) {
222 addresses.append( addressHash( address, counter ) );
223 counter++;
226 contactObject.insert( QLatin1String( "addresses" ), addresses );
228 setHashField( contactObject, QLatin1String( "mailer" ), rawContact.mailer() );
229 setHashField( contactObject, QLatin1String( "title" ), rawContact.title() );
230 setHashField( contactObject, QLatin1String( "role" ), rawContact.role() );
231 setHashField( contactObject, QLatin1String( "organization" ), rawContact.organization() );
232 setHashField( contactObject, QLatin1String( "department" ), rawContact.department() );
233 setHashField( contactObject, QLatin1String( "note" ), rawContact.note() );
234 setHashField( contactObject, QLatin1String( "profession" ), rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ) ) );
235 setHashField( contactObject, QLatin1String( "office" ), rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Office" ) ) );
236 setHashField( contactObject, QLatin1String( "manager" ), rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-ManagersName" ) ) );
237 setHashField( contactObject, QLatin1String( "assistant" ), rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-AssistantsName" ) ) );
238 setHashField( contactObject, QLatin1String( "spouse" ), rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-SpousesName" ) ) );
239 setHashField( contactObject, QLatin1String( "imAddress" ), rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-IMAddress" ) ) );
241 // Custom fields
243 QVariantList customFields;
245 static QSet<QString> blacklistedKeys;
246 if ( blacklistedKeys.isEmpty() ) {
247 blacklistedKeys.insert( QLatin1String( "CRYPTOPROTOPREF" ) );
248 blacklistedKeys.insert( QLatin1String( "OPENPGPFP" ) );
249 blacklistedKeys.insert( QLatin1String( "SMIMEFP" ) );
250 blacklistedKeys.insert( QLatin1String( "CRYPTOSIGNPREF" ) );
251 blacklistedKeys.insert( QLatin1String( "CRYPTOENCRYPTPREF" ) );
252 blacklistedKeys.insert( QLatin1String( "Anniversary" ) );
253 blacklistedKeys.insert( QLatin1String( "BlogFeed" ) );
254 blacklistedKeys.insert( QLatin1String( "Profession" ) );
255 blacklistedKeys.insert( QLatin1String( "Office" ) );
256 blacklistedKeys.insert( QLatin1String( "ManagersName" ) );
257 blacklistedKeys.insert( QLatin1String( "AssistantsName" ) );
258 blacklistedKeys.insert( QLatin1String( "SpousesName" ) );
259 blacklistedKeys.insert( QLatin1String( "IMAddress" ) );
260 blacklistedKeys.insert( QLatin1String( "AddressBook" ) );
263 if ( !rawContact.customs().empty() ) {
264 const QStringList customs = rawContact.customs();
265 foreach ( QString custom, customs ) { //krazy:exclude=foreach
266 if ( custom.startsWith( QLatin1String( "KADDRESSBOOK-" ) ) ) {
267 custom.remove( QLatin1String( "KADDRESSBOOK-X-" ) );
268 custom.remove( QLatin1String( "KADDRESSBOOK-" ) );
270 int pos = custom.indexOf( QLatin1Char( ':' ) );
271 QString key = custom.left( pos );
272 QString value = custom.mid( pos + 1 );
274 if ( blacklistedKeys.contains( key ) )
275 continue;
277 // check whether it is a custom local field
278 foreach ( const QVariantMap &description, customFieldDescriptions() ) {
279 if ( description.value( QLatin1String( "key" ) ).toString() == key ) {
280 key = description.value( QLatin1String( "title" ) ).toString();
281 if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "boolean" ) ) {
282 if ( value == QLatin1String( "true" ) )
283 value = i18nc( "Boolean value", "yes" );
284 else
285 value = i18nc( "Boolean value", "no" );
286 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "date" ) ) {
287 const QDate date = QDate::fromString( value, Qt::ISODate );
288 value = KGlobal::locale()->formatDate( date, KLocale::ShortDate );
289 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "time" ) ) {
290 const QTime time = QTime::fromString( value, Qt::ISODate );
291 value = KGlobal::locale()->formatTime( time );
292 } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "datetime" ) ) {
293 const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate );
294 value = KGlobal::locale()->formatDateTime( dateTime, KLocale::ShortDate );
296 break;
300 QVariantHash customFieldObject;
301 customFieldObject.insert( QLatin1String( "title" ), key );
302 customFieldObject.insert( QLatin1String( "value" ), value );
304 customFields.append( customFieldObject );
309 contactObject.insert( QLatin1String( "customFields" ), customFields );
311 QVariantHash colorsObject;
312 colorsObject.insert( "linkColor", KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() );
313 colorsObject.insert( "textColor", KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() );
314 colorsObject.insert( "backgroundColor", KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() );
316 QVariantHash mapping;
317 mapping.insert( "contact", contactObject );
318 mapping.insert( "colors", colorsObject );
320 Grantlee::Context context( mapping );
322 if ( form == SelfcontainedForm )
323 return d->mSelfcontainedTemplate->render( &context );
324 else if ( form == EmbeddableForm )
325 return d->mEmbeddableTemplate->render( &context );
326 else
327 return QString();