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

Skip menu "kdepimlibs-4.9.1 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • 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