22#include "contactviewer.h"
24#include "contactmetadata_p.h"
25#include "contactmetadataattribute_p.h"
26#include "customfieldmanager_p.h"
27#include "standardcontactformatter.h"
28#include "textbrowser_p.h"
30#include "editor/im/improtocols.h"
32#include <akonadi/collection.h>
33#include <akonadi/collectionfetchjob.h>
34#include <akonadi/entitydisplayattribute.h>
35#include <akonadi/item.h>
36#include <akonadi/itemfetchscope.h>
37#include <kabc/addressee.h>
38#include <kcolorscheme.h>
39#include <kconfiggroup.h>
42#include <klocalizedstring.h>
43#include <kstringhandler.h>
48#include <prison/QRCodeBarcode>
49#include <prison/DataMatrixBarcode>
50#include <kabc/vcardconverter.h>
55class ContactViewer::Private
59 : mParent( parent ), mParentCollectionFetchJob( 0 )
62 mContactFormatter = mStandardContactFormatter;
64 mQRCode =
new prison::QRCodeBarcode();
65 mDataMatrix =
new prison::DataMatrixBarcode();
71 delete mStandardContactFormatter;
78 void updateView(
const QVariantList &localCustomFieldDescriptions = QVariantList(),
const QString &addressBookName = QString() )
80 static QPixmap defaultPixmap = KIcon( QLatin1String(
"user-identity" ) ).pixmap( QSize( 100, 100 ) );
81 static QPixmap defaultMapPixmap = KIcon( QLatin1String(
"document-open-remote" ) ).pixmap( QSize( 16, 16 ) );
82 static QPixmap defaultSmsPixmap = KIcon( IMProtocols::self()->icon( QString::fromLatin1(
"messaging/sms" ) ) ).pixmap( QSize( 16, 16 ) );
83 mParent->setWindowTitle( i18n(
"Contact %1", mCurrentContact.assembledName() ) );
85 if ( mCurrentContact.photo().isIntern() ) {
86 mBrowser->document()->addResource( QTextDocument::ImageResource,
87 QUrl( QLatin1String(
"contact_photo" ) ),
88 mCurrentContact.photo().data() );
89 }
else if (!mCurrentContact.photo().url().isEmpty()) {
90 mBrowser->document()->addResource( QTextDocument::ImageResource,
91 QUrl( QLatin1String(
"contact_photo" ) ),
94 mBrowser->document()->addResource( QTextDocument::ImageResource,
95 QUrl( QLatin1String(
"contact_photo" ) ),
99 if ( mCurrentContact.logo().isIntern() ) {
100 mBrowser->document()->addResource( QTextDocument::ImageResource,
101 QUrl( QLatin1String(
"contact_logo" ) ),
102 mCurrentContact.logo().data() );
103 }
else if (!mCurrentContact.logo().url().isEmpty()) {
107 mBrowser->document()->addResource( QTextDocument::ImageResource,
108 QUrl( QLatin1String(
"map_icon" ) ),
111 mBrowser->document()->addResource( QTextDocument::ImageResource,
112 QUrl( QLatin1String(
"sms_icon" ) ),
116 KConfig config( QLatin1String(
"akonadi_contactrc" ) );
117 KConfigGroup group( &config, QLatin1String(
"View" ) );
118 if ( group.readEntry(
"QRCodes",
true ) ) {
119 KABC::VCardConverter converter;
120 KABC::Addressee addr( mCurrentContact );
121 addr.setPhoto( KABC::Picture() );
122 addr.setLogo( KABC::Picture() );
123 const QString data = QString::fromUtf8( converter.createVCard( addr ) );
124 mQRCode->setData( data );
125 mDataMatrix->setData( data );
126 mBrowser->document()->addResource( QTextDocument::ImageResource,
127 QUrl( QLatin1String(
"qrcode" ) ),
128 mQRCode->toImage( QSizeF( 50, 50 ) ) );
129 mBrowser->document()->addResource( QTextDocument::ImageResource,
130 QUrl( QLatin1String(
"datamatrix" ) ),
131 mDataMatrix->toImage( QSizeF( 50, 50 ) ) );
136 QList<QVariantMap> customFieldDescriptions;
137 foreach (
const QVariant &entry, localCustomFieldDescriptions ) {
138 customFieldDescriptions << entry.toMap();
141 const CustomField::List globalCustomFields = CustomFieldManager::globalCustomFieldDescriptions();
142 foreach (
const CustomField &field, globalCustomFields ) {
143 QVariantMap description;
144 description.insert( QLatin1String(
"key" ), field.key() );
145 description.insert( QLatin1String(
"title" ), field.title() );
147 customFieldDescriptions << description;
150 KABC::Addressee
contact( mCurrentContact );
151 if ( !addressBookName.isEmpty() ) {
152 contact.insertCustom( QLatin1String(
"KADDRESSBOOK" ), QLatin1String(
"AddressBook" ), addressBookName );
155 mContactFormatter->setContact(
contact );
156 mContactFormatter->setCustomFieldDescriptions( customFieldDescriptions );
158 mBrowser->setHtml( mContactFormatter->toHtml() );
161 void slotMailClicked(
const QString&,
const QString &email )
163 QString name, address;
166 KABC::Addressee::parseEmailAddress( email.mid( 7 ), name, address );
168 emit mParent->emailClicked( name, address );
171 void slotUrlClicked(
const QString &urlString )
173 KUrl url( urlString );
174 const QString urlScheme( url.scheme() );
175 if ( urlScheme == QLatin1String(
"http" ) ||
176 urlScheme == QLatin1String(
"https" ) ) {
177 emit mParent->urlClicked( url );
178 }
else if ( urlScheme == QLatin1String(
"phone" ) ) {
179 const int pos = url.queryItemValue( QLatin1String(
"index" ) ).toInt();
181 const KABC::PhoneNumber::List numbers = mCurrentContact.phoneNumbers();
182 if ( pos < numbers.count() ) {
183 emit mParent->phoneNumberClicked( numbers.at( pos ) );
185 }
else if ( urlScheme == QLatin1String(
"sms" ) ) {
186 const int pos = url.queryItemValue( QLatin1String(
"index" ) ).toInt();
188 const KABC::PhoneNumber::List numbers = mCurrentContact.phoneNumbers();
189 if ( pos < numbers.count() ) {
190 emit mParent->smsClicked( numbers.at( pos ) );
192 }
else if ( urlScheme == QLatin1String(
"address" ) ) {
193 const int pos = url.queryItemValue( QLatin1String(
"index" ) ).toInt();
195 const KABC::Address::List addresses = mCurrentContact.addresses();
196 if ( pos < addresses.count() ) {
197 emit mParent->addressClicked( addresses.at( pos ) );
202 void slotParentCollectionFetched( KJob *job )
204 mParentCollectionFetchJob = 0;
206 QString addressBookName;
208 if ( !job->error() ) {
212 addressBookName = collection.displayName();
218 metaData.
load( mCurrentItem );
225 KABC::Addressee mCurrentContact;
231 prison::AbstractBarcode* mQRCode;
232 prison::AbstractBarcode* mDataMatrix;
237 : QWidget( parent ), d( new Private( this ) )
239 QVBoxLayout *layout =
new QVBoxLayout(
this );
240 layout->setMargin( 0 );
243 d->mBrowser->setNotifyClick(
true );
245 connect( d->mBrowser, SIGNAL(mailClick(QString,QString)),
246 this, SLOT(slotMailClicked(QString,QString)) );
247 connect( d->mBrowser, SIGNAL(urlClick(QString)),
248 this, SLOT(slotUrlClicked(QString)) );
250 layout->addWidget( d->mBrowser );
270 return d->mCurrentContact;
275 if ( formatter == 0 ) {
276 d->mContactFormatter = d->mStandardContactFormatter;
278 d->mContactFormatter = formatter;
294void ContactViewer::itemChanged(
const Item &contactItem )
296 if ( !contactItem.hasPayload<KABC::Addressee>() ) {
300 d->mCurrentItem = contactItem;
301 d->mCurrentContact = contactItem.payload<KABC::Addressee>();
304 if ( d->mParentCollectionFetchJob ) {
305 disconnect( d->mParentCollectionFetchJob, SIGNAL(result(KJob*)),
this, SLOT(slotParentCollectionFetched(KJob*)) );
306 delete d->mParentCollectionFetchJob;
307 d->mParentCollectionFetchJob = 0;
311 connect( d->mParentCollectionFetchJob, SIGNAL(result(KJob*)), SLOT(slotParentCollectionFetched(KJob*)) );
314void ContactViewer::itemRemoved()
316 d->mBrowser->clear();
319#include "moc_contactviewer.cpp"
Job that fetches collections from the Akonadi storage.
@ Base
Only fetch the base collection.
Collection::List collections() const
Returns the list of fetched collection.
Represents a collection of PIM items.
void fetchAttribute(const QByteArray &type, bool fetch=true)
Sets whether the attribute of the given type should be fetched.
void setAncestorRetrieval(AncestorRetrieval ancestorDepth)
Sets how many levels of ancestor collections should be included in the retrieval.
void fetchFullPayload(bool fetch=true)
Sets whether the full payload shall be fetched.
@ Parent
Only retrieve the immediate parent collection.
void setItem(const Item &item)
Sets the item that shall be monitored.
Item item() const
Returns the currently monitored item.
ItemFetchScope & fetchScope()
Returns the item fetch scope.
A convenience class to remove the 'Copy Link Location' action from the context menu of KTextBrowser.
A class that represents non-standard contact fields.
FreeBusyManager::Singleton.