• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

akonadi/contact

  • akonadi
  • contact
standardcontactformatter.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  Copyright (c) 2010 Tobias Koenig <tokoe@kde.org>
5 
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.
10 
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.
15 
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.
20 */
21 
22 #include "standardcontactformatter.h"
23 
24 #include <akonadi/item.h>
25 #include <kabc/addressee.h>
26 #include <kcolorscheme.h>
27 #include <kconfiggroup.h>
28 #include <kglobal.h>
29 #include <klocale.h>
30 #include <kstringhandler.h>
31 
32 #include <QtCore/QSet>
33 #include <QTextDocument>
34 
35 using namespace Akonadi;
36 
37 class StandardContactFormatter::Private
38 {
39 public:
40  Private()
41  :displayQRcode(true)
42  {
43 
44  }
45 
46  bool displayQRcode;
47 };
48 
49 StandardContactFormatter::StandardContactFormatter()
50  : d( new Private() )
51 {
52 }
53 
54 StandardContactFormatter::~StandardContactFormatter()
55 {
56  delete d;
57 }
58 
59 static int contactAge( const QDate &date )
60 {
61  QDate now = QDate::currentDate();
62  int age = now.year() - date.year();
63  if ( date > now.addYears( -age ) ) {
64  age--;
65  }
66  return age;
67 }
68 
69 QString StandardContactFormatter::toHtml( HtmlForm form ) const
70 {
71  KABC::Addressee rawContact;
72  const Akonadi::Item localItem = item();
73  if ( localItem.isValid() && localItem.hasPayload<KABC::Addressee>() ) {
74  rawContact = localItem.payload<KABC::Addressee>();
75  } else {
76  rawContact = contact();
77  }
78 
79  if ( rawContact.isEmpty() ) {
80  return QString();
81  }
82 
83  // We'll be building a table to display the vCard in.
84  // Each row of the table will be built using this string for its HTML.
85 
86  QString rowFmtStr = QString::fromLatin1(
87  "<tr>"
88  "<td align=\"right\" valign=\"top\" width=\"30%\"><b><font color=\"grey\">%1</font></b></td>\n"
89  "<td align=\"left\" valign=\"top\" width=\"70%\"><font>%2</font></td>\n"
90  "</tr>\n"
91  );
92 
93  // Build the table's rows here
94  QString dynamicPart;
95 
96  // Birthday
97  const QDate date = rawContact.birthday().date();
98  const int years = contactAge( date );
99 
100  if ( date.isValid() ) {
101  dynamicPart += rowFmtStr
102  .arg( KABC::Addressee::birthdayLabel() )
103  .arg( KGlobal::locale()->formatDate( date ) +
104  QLatin1String( "&nbsp;&nbsp;" ) + i18np( "(One year old)", "(%1 years old)", years ) );
105  }
106 
107  // Phone Numbers
108  int counter = 0;
109  foreach ( const KABC::PhoneNumber &number, rawContact.phoneNumbers() ) {
110 
111  QString url;
112  if ( number.type() & KABC::PhoneNumber::Cell ) {
113  url = QString::fromLatin1( "<a href=\"phone:?index=%1\">%2</a> (<a href=\"sms:?index=%1\">SMS</a>)" ).arg( counter ).arg( Qt::escape( number.number() ) );
114  } else {
115  url = QString::fromLatin1( "<a href=\"phone:?index=%1\">%2</a>" ).arg( counter ).arg( Qt::escape( number.number() ) );
116  }
117 
118  counter++;
119 
120  dynamicPart += rowFmtStr
121  .arg( number.typeLabel().replace( QLatin1String( " " ), QLatin1String( "&nbsp;" ) ) )
122  .arg( url );
123  }
124 
125  // EMails
126  foreach ( const QString &email, rawContact.emails() ) {
127  const QString type = i18nc( "a contact's email address", "Email" );
128 
129  const QString fullEmail = QString::fromLatin1( KUrl::toPercentEncoding( rawContact.fullEmail( email ) ) );
130 
131  dynamicPart += rowFmtStr.arg( type )
132  .arg( QString::fromLatin1( "<a href=\"mailto:%1\">%2</a>" )
133  .arg( fullEmail, email ) );
134  }
135 
136  // Homepage
137  if ( rawContact.url().isValid() ) {
138  QString url = rawContact.url().url();
139  if ( !url.startsWith( QLatin1String( "http://" ) ) && !url.startsWith( QLatin1String( "https://" ) ) ) {
140  url = QLatin1String( "http://" ) + url;
141  }
142 
143  url = KStringHandler::tagUrls( Qt::escape( url ) );
144  dynamicPart += rowFmtStr.arg( i18n( "Homepage" ) ).arg( url );
145  }
146 
147  // Blog Feed
148  const QString blog = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "BlogFeed" ) );
149  if ( !blog.isEmpty() ) {
150  dynamicPart += rowFmtStr.arg( i18n( "Blog Feed" ) ).arg( KStringHandler::tagUrls( Qt::escape( blog ) ) );
151  }
152 
153  // Addresses
154  counter = 0;
155  foreach ( const KABC::Address &address, rawContact.addresses() ) {
156  QString formattedAddress;
157 
158  if ( address.label().isEmpty() ) {
159  formattedAddress = Qt::escape( address.formattedAddress().trimmed() );
160  } else {
161  formattedAddress = Qt::escape( address.label() );
162  }
163 
164  formattedAddress = formattedAddress.replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) );
165 
166  const QString url = QString::fromLatin1( "%1 <a href=\"address:?index=%2\"><img src=\"map_icon\" alt=\"%3\"/></a>" )
167  .arg( formattedAddress )
168  .arg( counter )
169  .arg( i18n( "Show address on map" ) );
170  counter++;
171 
172  dynamicPart += rowFmtStr
173  .arg( KABC::Address::typeLabel( address.type() ) )
174  .arg( url );
175  }
176 
177  // Note
178  QString notes;
179  if ( !rawContact.note().isEmpty() ) {
180  notes = rowFmtStr.arg( i18n( "Notes" ) ).arg( Qt::escape( rawContact.note() ).replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) ) ) ;
181  }
182 
183  // Custom Data
184  QString customData;
185  static QMap<QString, QString> titleMap;
186  if ( titleMap.isEmpty() ) {
187  titleMap.insert( QLatin1String( "Department" ), i18n( "Department" ) );
188  titleMap.insert( QLatin1String( "Profession" ), i18n( "Profession" ) );
189  titleMap.insert( QLatin1String( "AssistantsName" ), i18n( "Assistant's Name" ) );
190  titleMap.insert( QLatin1String( "ManagersName" ), i18n( "Manager's Name" ) );
191  titleMap.insert( QLatin1String( "SpousesName" ), i18nc( "Wife/Husband/...", "Partner's Name" ) );
192  titleMap.insert( QLatin1String( "Office" ), i18n( "Office" ) );
193  titleMap.insert( QLatin1String( "IMAddress" ), i18n( "IM Address" ) );
194  titleMap.insert( QLatin1String( "Anniversary" ), i18n( "Anniversary" ) );
195  titleMap.insert( QLatin1String( "AddressBook" ), i18n( "Address Book" ) );
196  }
197 
198  static QSet<QString> blacklistedKeys;
199  if ( blacklistedKeys.isEmpty() ) {
200  blacklistedKeys.insert( QLatin1String( "CRYPTOPROTOPREF" ) );
201  blacklistedKeys.insert( QLatin1String( "OPENPGPFP" ) );
202  blacklistedKeys.insert( QLatin1String( "SMIMEFP" ) );
203  blacklistedKeys.insert( QLatin1String( "CRYPTOSIGNPREF" ) );
204  blacklistedKeys.insert( QLatin1String( "CRYPTOENCRYPTPREF" ) );
205  blacklistedKeys.insert( QLatin1String( "MailPreferedFormatting" ) );
206  blacklistedKeys.insert( QLatin1String( "MailAllowToRemoteContent" ) );
207  }
208 
209  if ( !rawContact.customs().empty() ) {
210  const QStringList customs = rawContact.customs();
211  foreach ( QString custom, customs ) { //krazy:exclude=foreach
212  if ( custom.startsWith( QLatin1String( "KADDRESSBOOK-" ) ) ) {
213  custom.remove( QLatin1String( "KADDRESSBOOK-X-" ) );
214  custom.remove( QLatin1String( "KADDRESSBOOK-" ) );
215 
216  int pos = custom.indexOf( QLatin1Char( ':' ) );
217  QString key = custom.left( pos );
218  QString value = custom.mid( pos + 1 );
219 
220  // convert anniversary correctly
221  if ( key == QLatin1String( "Anniversary" ) || key == QLatin1String( "ANNIVERSARY" ) ) {
222  const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate );
223  value = KGlobal::locale()->formatDate( dateTime.date() );
224  } else if ( key == QLatin1String( "BlogFeed" ) ) { // blog is handled separated
225  continue;
226  } else if ( blacklistedKeys.contains( key ) ) {
227  continue;
228  }
229 
230  // check whether we have a mapping for the title
231  const QMap<QString, QString>::ConstIterator keyIt = titleMap.constFind( key );
232  if ( keyIt != titleMap.constEnd() ) {
233  key = keyIt.value();
234  } else {
235  // check whether it is a custom local field
236  foreach ( const QVariantMap &description, customFieldDescriptions() ) {
237  if ( description.value( QLatin1String( "key" ) ).toString() == key ) {
238  key = description.value( QLatin1String( "title" ) ).toString();
239  if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "boolean" ) ) {
240  if ( value == QLatin1String( "true" ) ) {
241  value = i18nc( "Boolean value", "yes" );
242  } else {
243  value = i18nc( "Boolean value", "no" );
244  }
245  } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "date" ) ) {
246  const QDate date = QDate::fromString( value, Qt::ISODate );
247  value = KGlobal::locale()->formatDate( date, KLocale::ShortDate );
248  } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "time" ) ) {
249  const QTime time = QTime::fromString( value, Qt::ISODate );
250  value = KGlobal::locale()->formatTime( time );
251  } else if ( description.value( QLatin1String( "type" ) ) == QLatin1String( "datetime" ) ) {
252  const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate );
253  value = KGlobal::locale()->formatDateTime( dateTime, KLocale::ShortDate );
254  }
255  break;
256  }
257  }
258  }
259 
260  customData += rowFmtStr.arg( key ).arg( Qt::escape( value ) ) ;
261  }
262  }
263  }
264 
265  // Assemble all parts
266  QString role = rawContact.title();
267  if ( role.isEmpty() ) {
268  role = rawContact.role();
269  }
270  if ( role.isEmpty() ) {
271  role = rawContact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ) );
272  }
273 
274  QString strAddr = QString::fromLatin1(
275  "<div align=\"center\">"
276  "<table cellpadding=\"3\" cellspacing=\"0\">"
277  "<tr>"
278  "<td align=\"right\" valign=\"top\" width=\"30%\" rowspan=\"3\">"
279  "<img src=\"%1\" width=\"100\" vspace=\"1\">" // image
280  "</td>"
281  "<td align=\"left\" width=\"70%\"><font size=\"+2\"><b>%2</b></font></td>" // name
282  "</tr>"
283  "<tr>"
284  "<td align=\"left\" width=\"70%\">%3</td>" // role
285  "</tr>"
286  "<tr>"
287  "<td align=\"left\" width=\"70%\">%4</td>" // organization
288  "</tr>")
289  .arg( QLatin1String( "contact_photo" ) )
290  .arg( Qt::escape( rawContact.realName() ) )
291  .arg( Qt::escape( role ) )
292  .arg( Qt::escape( rawContact.organization() ) );
293 
294  strAddr.append( dynamicPart );
295  strAddr.append( notes );
296  strAddr.append( customData );
297  strAddr.append( QString::fromLatin1( "</table>" ) );
298 
299 #ifdef HAVE_PRISON
300  if(d->displayQRcode) {
301  KConfig config( QLatin1String( "akonadi_contactrc" ) );
302  KConfigGroup group( &config, QLatin1String( "View" ) );
303  if ( group.readEntry( "QRCodes", true ) ) {
304  strAddr.append( QString::fromLatin1(
305  "<p align=\"center\">"
306  "<img src=\"%1\" vspace=\"1\">"
307  "<img src=\"%2\" vspace=\"1\">"
308  "</p>"
309  )
310  .arg( QLatin1String( "datamatrix" ) )
311  .arg( QLatin1String( "qrcode" ) ) );
312  }
313  }
314 #endif // HAVE_PRISON
315 
316  strAddr.append( QString::fromLatin1( "</div>\n" ) );
317 
318  if ( form == EmbeddableForm ) {
319  return strAddr;
320  }
321 
322  const QString document = QString::fromLatin1(
323  "<html>"
324  "<head>"
325  " <style type=\"text/css\">"
326  " a {text-decoration:none; color:%1}"
327  " </style>"
328  "</head>"
329  "<body text=\"%1\" bgcolor=\"%2\">" // text and background color
330  "%3" // contact part
331  "</body>"
332  "</html>" )
333  .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() )
334  .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() )
335  .arg( strAddr );
336 
337  return document;
338 }
339 
340 void StandardContactFormatter::setDisplayQRCode( bool show )
341 {
342  d->displayQRcode = show;
343 }
344 
345 bool StandardContactFormatter::displayQRCode() const
346 {
347  return d->displayQRcode;
348 }
349 
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jul 13 2013 01:28:43 by doxygen 1.8.3.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi/contact

Skip menu "akonadi/contact"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.10.5 API Reference

Skip menu "kdepimlibs-4.10.5 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal