• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

akonadi/contact

contactviewer.cpp

00001 /*
00002     This file is part of Akonadi Contact.
00003 
00004     Copyright (c) 2009 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 "contactviewer.h"
00023 
00024 #include "textbrowser_p.h"
00025 
00026 #include <akonadi/item.h>
00027 #include <akonadi/itemfetchscope.h>
00028 #include <kabc/addressee.h>
00029 #include <kcolorscheme.h>
00030 #include <kglobal.h>
00031 #include <kicon.h>
00032 #include <klocale.h>
00033 #include <kstringhandler.h>
00034 
00035 #include <QtGui/QVBoxLayout>
00036 
00037 using namespace Akonadi;
00038 
00039 static QString contactAsHtml( const KABC::Addressee &contact );
00040 
00041 class ContactViewer::Private
00042 {
00043   public:
00044     Private( ContactViewer *parent )
00045       : mParent( parent )
00046     {
00047     }
00048 
00049     void slotMailClicked( const QString&, const QString &email )
00050     {
00051       QString name, address;
00052 
00053       // remove the 'mailto:' and split into name and email address
00054       KABC::Addressee::parseEmailAddress( email.mid( 7 ), name, address );
00055 
00056       emit mParent->emailClicked( name, address );
00057     }
00058 
00059     void slotUrlClicked( const QString &urlString )
00060     {
00061       KUrl url( urlString );
00062 
00063       if ( url.scheme() == QLatin1String( "http" ) ||
00064            url.scheme() == QLatin1String( "https" ) ) {
00065         emit mParent->urlClicked( url );
00066       } else if ( url.scheme() == QLatin1String( "phone" ) ) {
00067         const int pos = url.queryItemValue( QLatin1String( "index" ) ).toInt();
00068 
00069         const KABC::PhoneNumber::List numbers = mCurrentContact.phoneNumbers();
00070         if ( pos < numbers.count() ) {
00071           emit mParent->phoneNumberClicked( numbers.at( pos ) );
00072         }
00073       } else if ( url.scheme() == QLatin1String( "address" ) ) {
00074         const int pos = url.queryItemValue( QLatin1String( "index" ) ).toInt();
00075 
00076         const KABC::Address::List addresses = mCurrentContact.addresses();
00077         if ( pos < addresses.count() ) {
00078           emit mParent->addressClicked( addresses.at( pos ) );
00079         }
00080       }
00081     }
00082 
00083     ContactViewer *mParent;
00084     TextBrowser *mBrowser;
00085     KABC::Addressee mCurrentContact;
00086 };
00087 
00088 ContactViewer::ContactViewer( QWidget *parent )
00089   : QWidget( parent ), d( new Private( this ) )
00090 {
00091   QVBoxLayout *layout = new QVBoxLayout( this );
00092   layout->setMargin( 0 );
00093 
00094   d->mBrowser = new TextBrowser;
00095   d->mBrowser->setNotifyClick( true );
00096 
00097   connect( d->mBrowser, SIGNAL( mailClick( const QString&, const QString& ) ),
00098            this, SLOT( slotMailClicked( const QString&, const QString& ) ) );
00099   connect( d->mBrowser, SIGNAL( urlClick( const QString& ) ),
00100            this, SLOT( slotUrlClicked( const QString& ) ) );
00101 
00102   layout->addWidget( d->mBrowser );
00103 
00104   // always fetch full payload for contacts
00105   fetchScope().fetchFullPayload();
00106 }
00107 
00108 ContactViewer::~ContactViewer()
00109 {
00110   delete d;
00111 }
00112 
00113 Akonadi::Item ContactViewer::contact() const
00114 {
00115   return ItemMonitor::item();
00116 }
00117 
00118 void ContactViewer::setContact( const Akonadi::Item &contact )
00119 {
00120   ItemMonitor::setItem( contact );
00121 }
00122 
00123 void ContactViewer::itemChanged( const Item &contactItem )
00124 {
00125   if ( !contactItem.hasPayload<KABC::Addressee>() )
00126     return;
00127 
00128   static QPixmap defaultPixmap = KIcon( QLatin1String( "x-office-contact" ) ).pixmap( QSize( 100, 140 ) );
00129 
00130   d->mCurrentContact = contactItem.payload<KABC::Addressee>();
00131 
00132   setWindowTitle( i18n( "Contact %1", d->mCurrentContact.assembledName() ) );
00133 
00134   if ( d->mCurrentContact.photo().isIntern() ) {
00135     d->mBrowser->document()->addResource( QTextDocument::ImageResource,
00136                                           QUrl( QLatin1String( "contact_photo" ) ),
00137                                           d->mCurrentContact.photo().data() );
00138   } else {
00139     d->mBrowser->document()->addResource( QTextDocument::ImageResource,
00140                                           QUrl( QLatin1String( "contact_photo" ) ),
00141                                           defaultPixmap );
00142   }
00143 
00144   d->mBrowser->setHtml( contactAsHtml( d->mCurrentContact ) );
00145 }
00146 
00147 void ContactViewer::itemRemoved()
00148 {
00149   d->mBrowser->clear();
00150 }
00151 
00152 static QString contactAsHtml( const KABC::Addressee &contact )
00153 {
00154   // We'll be building a table to display the vCard in.
00155   // Each row of the table will be built using this string for its HTML.
00156 
00157   QString rowFmtStr = QString::fromLatin1(
00158         "<tr>"
00159         "<td align=\"right\" valign=\"top\" width=\"30%\"><b><font size=\"-1\" color=\"grey\">%1</font></b></td>\n"
00160         "<td align=\"left\" valign=\"top\" width=\"70%\"><font size=\"-1\">%2</font></td>\n"
00161         "</tr>\n"
00162         );
00163 
00164   // Build the table's rows here
00165   QString dynamicPart;
00166 
00167   // Birthday
00168   const QDate date = contact.birthday().date();
00169 
00170   if ( date.isValid() )
00171     dynamicPart += rowFmtStr
00172       .arg( KABC::Addressee::birthdayLabel() )
00173       .arg( KGlobal::locale()->formatDate( date, KLocale::ShortDate ) );
00174 
00175   // Phone Numbers
00176   int counter = 0;
00177   foreach ( const KABC::PhoneNumber &number, contact.phoneNumbers() ) {
00178       const QString url = QString::fromLatin1( "<a href=\"phone:?index=%1\">%2</a>" ).arg( counter ).arg( number.number() );
00179       counter++;
00180 
00181       dynamicPart += rowFmtStr
00182         .arg( KABC::PhoneNumber::typeLabel( number.type() ).replace( QLatin1String( " " ), QLatin1String( "&nbsp;" ) ) )
00183         .arg( url );
00184   }
00185 
00186   // EMails
00187   foreach ( const QString &email, contact.emails() ) {
00188     QString type = i18nc( "a contact's email address", "Email" );
00189 
00190     const QString fullEmail = QString::fromLatin1( KUrl::toPercentEncoding( contact.fullEmail( email ) ) );
00191 
00192     dynamicPart += rowFmtStr.arg( type )
00193       .arg( QString::fromLatin1( "<a href=\"mailto:%1\">%2</a>" )
00194       .arg( fullEmail, email ) );
00195   }
00196 
00197   // Homepage
00198   if ( contact.url().isValid() ) {
00199     QString url = contact.url().url();
00200     if ( !url.startsWith( QLatin1String( "http://" ) ) && !url.startsWith( QLatin1String( "https://" ) ) )
00201       url = QLatin1String( "http://" ) + url;
00202 
00203     url = KStringHandler::tagUrls( url );
00204     dynamicPart += rowFmtStr.arg( i18n( "Homepage" ) ).arg( url );
00205   }
00206 
00207   // Blog Feed
00208   const QString blog = contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "BlogFeed" ) );
00209   if ( !blog.isEmpty() )
00210     dynamicPart += rowFmtStr.arg( i18n( "Blog Feed" ) ).arg( KStringHandler::tagUrls( blog ) );
00211 
00212   // Addresses
00213   counter = 0;
00214   foreach ( const KABC::Address &address, contact.addresses() ) {
00215     QString formattedAddress;
00216 
00217     if ( address.label().isEmpty() ) {
00218       formattedAddress = address.formattedAddress().trimmed();
00219     } else {
00220       formattedAddress = address.label();
00221     }
00222 
00223     formattedAddress = formattedAddress.replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) );
00224 
00225     const QString url = QString::fromLatin1( "<a href=\"address:?index=%1\">%2</a>" ).arg( counter).arg( formattedAddress );
00226     counter++;
00227 
00228     dynamicPart += rowFmtStr
00229       .arg( KABC::Address::typeLabel( address.type() ) )
00230       .arg( url );
00231   }
00232 
00233   // Note
00234   QString notes;
00235   if ( !contact.note().isEmpty() )
00236     notes = rowFmtStr.arg( i18n( "Notes" ) ).arg( contact.note().replace( QLatin1Char( '\n' ), QLatin1String( "<br>" ) ) ) ;
00237 
00238   // Custom Data
00239   QString customData;
00240   static QMap<QString, QString> titleMap;
00241   if ( titleMap.isEmpty() ) {
00242     titleMap.insert( QLatin1String( "Department" ), i18n( "Department" ) );
00243     titleMap.insert( QLatin1String( "Profession" ), i18n( "Profession" ) );
00244     titleMap.insert( QLatin1String( "AssistantsName" ), i18n( "Assistant's Name" ) );
00245     titleMap.insert( QLatin1String( "ManagersName" ), i18n( "Manager's Name" ) );
00246     titleMap.insert( QLatin1String( "SpousesName" ), i18nc( "Wife/Husband/...", "Partner's Name" ) );
00247     titleMap.insert( QLatin1String( "Office" ), i18n( "Office" ) );
00248     titleMap.insert( QLatin1String( "IMAddress" ), i18n( "IM Address" ) );
00249     titleMap.insert( QLatin1String( "Anniversary" ), i18n( "Anniversary" ) );
00250   }
00251 
00252   static QSet<QString> blacklistedKeys;
00253   if ( blacklistedKeys.isEmpty() ) {
00254     blacklistedKeys.insert( QLatin1String( "CRYPTOPROTOPREF" ) );
00255     blacklistedKeys.insert( QLatin1String( "OPENPGPFP" ) );
00256     blacklistedKeys.insert( QLatin1String( "SMIMEFP" ) );
00257     blacklistedKeys.insert( QLatin1String( "CRYPTOSIGNPREF" ) );
00258     blacklistedKeys.insert( QLatin1String( "CRYPTOENCRYPTPREF" ) );
00259   }
00260 
00261   if ( !contact.customs().empty() ) {
00262     const QStringList customs = contact.customs();
00263     foreach ( QString custom, customs ) { //krazy:exclude=foreach
00264       if ( custom.startsWith( QLatin1String( "KADDRESSBOOK-" ) ) ) {
00265         custom.remove( QLatin1String( "KADDRESSBOOK-X-" ) );
00266         custom.remove( QLatin1String( "KADDRESSBOOK-" ) );
00267 
00268         int pos = custom.indexOf( QLatin1Char( ':' ) );
00269         QString key = custom.left( pos );
00270         QString value = custom.mid( pos + 1 );
00271 
00272         // convert anniversary correctly
00273         if ( key == QLatin1String( "Anniversary" ) ) {
00274           const QDateTime dateTime = QDateTime::fromString( value, Qt::ISODate );
00275           value = KGlobal::locale()->formatDate( dateTime.date(), KLocale::ShortDate );
00276         }
00277 
00278         // blog is handled separated
00279         if ( key == QLatin1String( "BlogFeed" ) )
00280           continue;
00281 
00282         if ( blacklistedKeys.contains( key ) )
00283           continue;
00284 
00285         const QMap<QString, QString>::ConstIterator keyIt = titleMap.constFind( key );
00286         if ( keyIt != titleMap.constEnd() )
00287           key = keyIt.value();
00288 
00289         customData += rowFmtStr.arg( key ).arg( value ) ;
00290       }
00291     }
00292   }
00293 
00294   // Assemble all parts
00295   QString role = contact.title();
00296   if ( role.isEmpty() )
00297     role = contact.role();
00298   if ( role.isEmpty() )
00299     role = contact.custom( QLatin1String( "KADDRESSBOOK" ), QLatin1String( "X-Profession" ) );
00300 
00301   QString strAddr = QString::fromLatin1(
00302     "<div align=\"center\">"
00303     "<table cellpadding=\"3\" cellspacing=\"0\">"
00304     "<tr>"
00305     "<td align=\"right\" valign=\"top\" width=\"30%\" rowspan=\"3\">"
00306     "<img src=\"%1\" width=\"100\" vspace=\"1\">" // image
00307     "</td>"
00308     "<td align=\"left\" width=\"70%\"><font size=\"+2\"><b>%2</b></font></td>" // name
00309     "</tr>"
00310     "<tr>"
00311     "<td align=\"left\" width=\"70%\">%3</td>"  // role
00312     "</tr>"
00313     "<tr>"
00314     "<td align=\"left\" width=\"70%\">%4</td>"  // organization
00315     "</tr>")
00316       .arg( QLatin1String( "contact_photo" ) )
00317       .arg( contact.realName() )
00318       .arg( role )
00319       .arg( contact.organization() );
00320 
00321   strAddr.append( dynamicPart );
00322   strAddr.append( notes );
00323   strAddr.append( customData );
00324   strAddr.append( QString::fromLatin1( "</table></div>\n" ) );
00325 
00326   const QString document = QString::fromLatin1(
00327     "<html>"
00328     "<head>"
00329     " <style type=\"text/css\">"
00330     "  a {text-decoration:none; color:%1}"
00331     " </style>"
00332     "</head>"
00333     "<body text=\"%1\" bgcolor=\"%2\">" // text and background color
00334     "%3" // contact part
00335     "</body>"
00336     "</html>" )
00337      .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() )
00338      .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() )
00339      .arg( strAddr );
00340 
00341   return document;
00342 }
00343 
00344 #include "contactviewer.moc"

akonadi/contact

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal