~ubuntu-branches/ubuntu/karmic/kdepim/karmic-backports

« back to all changes in this revision

Viewing changes to akonadi/libkdepim-copy/addresseeview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi, Alessandro Ghersi, Harald Sitter
  • Date: 2009-06-27 04:40:05 UTC
  • mfrom: (1.1.39 upstream)
  • Revision ID: james.westby@ubuntu.com-20090627044005-4y2vm9xz7rvmzi4p
Tags: 4:4.2.95svn20090701-0ubuntu1
[ Alessandro Ghersi ]
* New upstream release
  - Bump build-deps
* Remove akonadi-kde and libmaildir4 packages
  - remove akonadi-kde.install and libmaildir4.install
  - remove libmaildir4 from debian/rules
  - remove akonadi-kde and libmaildir4 from depends
  - remove akonadi-kde and libmaildir4 from installgen
* Update kdepim-dev.install
* Update kpilot.install
* Add akonadi-kde and libmaildir4 transitional packages

[ Harald Sitter ]
* KAddressbook replaces Kontact << 4.2.85 (LP: #378373)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of libkdepim.
 
3
 
 
4
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
 
5
 
 
6
    This library is free software; you can redistribute it and/or
 
7
    modify it under the terms of the GNU Library General Public
 
8
    License as published by the Free Software Foundation; either
 
9
    version 2 of the License, or (at your option) any later version.
 
10
 
 
11
    This library is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
    Library General Public 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
 
18
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
19
    Boston, MA 02110-1301, USA.
 
20
*/
 
21
 
 
22
#include "addresseeview.h"
 
23
#include "sendsmsdialog.h"
 
24
 
 
25
#include <kabc/address.h>
 
26
#include <kabc/addressee.h>
 
27
#include <kabc/phonenumber.h>
 
28
#include <kabc/resource.h>
 
29
#include <kabc/resourceabc.h>
 
30
 
 
31
#include <KApplication>
 
32
#include <KCodecs>
 
33
#include <KColorScheme>
 
34
#include <KConfig>
 
35
#include <KDebug>
 
36
#include <KGlobal>
 
37
#include <KGlobalSettings>
 
38
#include <KIconLoader>
 
39
#include <KLocale>
 
40
#include <KMessageBox>
 
41
#include <KRun>
 
42
#include <KStringHandler>
 
43
#include <KTemporaryFile>
 
44
#include <KToggleAction>
 
45
#include <KToolInvocation>
 
46
#include <KUrl>
 
47
#include <kio/job.h>
 
48
 
 
49
#include <QBuffer>
 
50
#include <QContextMenuEvent>
 
51
#include <QImage>
 
52
#include <QMenu>
 
53
#include <QPixmap>
 
54
#include <QTextStream>
 
55
 
 
56
using namespace KPIM;
 
57
 
 
58
AddresseeView::AddresseeView( QWidget *parent, KConfig *config )
 
59
  : KTextBrowser( parent ), mDefaultConfig( false ), mImageJob( 0 ),
 
60
    mLinkMask( AddressLinks | EmailLinks | PhoneLinks | URLLinks | IMLinks | CustomFields )
 
61
{
 
62
  setWordWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere );
 
63
  setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
 
64
  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
 
65
 
 
66
  connect( this, SIGNAL( mailClick( const QString&, const QString& ) ),
 
67
           this, SLOT( slotMailClicked( const QString&, const QString& ) ) );
 
68
  connect( this, SIGNAL( urlClick( const QString& ) ),
 
69
           this, SLOT( slotUrlClicked( const QString& ) ) );
 
70
  connect( this, SIGNAL( highlighted( const QString& ) ),
 
71
           this, SLOT( slotHighlighted( const QString& ) ) );
 
72
 
 
73
  setNotifyClick( true );
 
74
 
 
75
  mActionShowBirthday = new KToggleAction( i18n( "Show Birthday" ), this );
 
76
  mActionShowAddresses = new KToggleAction( i18n( "Show Postal Addresses" ), this );
 
77
  mActionShowEmails = new KToggleAction( i18n( "Show Email Addresses" ), this );
 
78
  mActionShowPhones = new KToggleAction( i18n( "Show Telephone Numbers" ), this );
 
79
  mActionShowURLs = new KToggleAction( i18n( "Show Web Pages (URLs)" ), this );
 
80
  mActionShowIMAddresses = new KToggleAction( i18n( "Show Instant Messaging Addresses" ), this );
 
81
  mActionShowCustomFields = new KToggleAction( i18n( "Show Custom Fields" ), this );
 
82
 
 
83
  if ( !config ) {
 
84
    mConfig = new KConfig( "kaddressbookrc" );
 
85
    mDefaultConfig = true;
 
86
  } else {
 
87
    mConfig = config;
 
88
  }
 
89
 
 
90
  load();
 
91
 
 
92
  connect( mActionShowBirthday, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
93
  connect( mActionShowAddresses, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
94
  connect( mActionShowEmails, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
95
  connect( mActionShowPhones, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
96
  connect( mActionShowURLs, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
97
  connect( mActionShowIMAddresses, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
98
  connect( mActionShowCustomFields, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
 
99
 
 
100
  // set up IMProxy to display contacts' IM presence and make connections to keep the display live
 
101
  mKIMProxy = ::KIMProxy::instance();
 
102
  connect( mKIMProxy, SIGNAL( sigContactPresenceChanged( const QString& ) ),
 
103
           this, SLOT( slotPresenceChanged( const QString& ) ) );
 
104
  connect( mKIMProxy, SIGNAL( sigPresenceInfoExpired() ),
 
105
           this, SLOT( slotPresenceInfoExpired() ) );
 
106
}
 
107
 
 
108
AddresseeView::~AddresseeView()
 
109
{
 
110
  if ( mDefaultConfig )
 
111
    delete mConfig;
 
112
  mConfig = 0;
 
113
 
 
114
  delete mActionShowBirthday;
 
115
  delete mActionShowAddresses;
 
116
  delete mActionShowEmails;
 
117
  delete mActionShowPhones;
 
118
  delete mActionShowURLs;
 
119
  delete mActionShowIMAddresses;
 
120
  delete mActionShowCustomFields;
 
121
 
 
122
  mKIMProxy = 0;
 
123
}
 
124
 
 
125
void AddresseeView::setAddressee( const KABC::Addressee& addr )
 
126
{
 
127
  mAddressee = addr;
 
128
 
 
129
  if ( mImageJob ) {
 
130
    mImageJob->kill();
 
131
    mImageJob = 0;
 
132
  }
 
133
 
 
134
  mImageData.truncate( 0 );
 
135
 
 
136
  updateView();
 
137
}
 
138
 
 
139
void AddresseeView::enableLinks( int linkMask )
 
140
{
 
141
  mLinkMask = linkMask;
 
142
}
 
143
 
 
144
QString AddresseeView::vCardAsHTML( const KABC::Addressee& addr, ::KIMProxy*, LinkMask linkMask,
 
145
                                    bool internalLoading, FieldMask fieldMask )
 
146
{
 
147
  QString image = QString( "contact_%1_image" ).arg( addr.uid() );
 
148
 
 
149
  // Style strings from Gentix; this is just an initial version.
 
150
  //
 
151
  // These will be substituted into various HTML strings with .arg().
 
152
  // Search for @STYLE@ to find where. Note how we use %1 as a
 
153
  // placeholder where we fill in something else (in this case,
 
154
  // the global background color).
 
155
  //
 
156
  QString cellStyle = QString::fromLatin1(
 
157
        "style=\""
 
158
        "padding-right: 2px; "
 
159
        "border-right: #000 dashed 1px;\"" );
 
160
  QString cellStyle2 = QString::fromLatin1(
 
161
        "style=\""
 
162
        "padding-left: 2px;\"" );
 
163
  QString tableStyle = QString::fromLatin1(
 
164
        "style=\""
 
165
        "border: solid 1px; "
 
166
        "margin: 0em;\"");
 
167
 
 
168
  // We'll be building a table to display the vCard in.
 
169
  // Each row of the table will be built using this string for its HTML.
 
170
  //
 
171
  QString rowFmtStr = QString::fromLatin1(
 
172
        "<tr>"
 
173
        "<td align=\"right\" valign=\"top\" width=\"30%\" "); // Tag unclosed
 
174
  rowFmtStr.append( cellStyle );
 
175
  rowFmtStr.append( QString::fromLatin1(
 
176
        ">" // Close tag
 
177
        "<b>%1</b>"
 
178
        "</td>"
 
179
        "<td align=\"left\" valign=\"top\" width=\"70%\" ") ); // Tag unclosed
 
180
  rowFmtStr.append( cellStyle2 );
 
181
  rowFmtStr.append( QString::fromLatin1(
 
182
        ">" // Close tag
 
183
        "%2"
 
184
        "</td>"
 
185
        "</tr>\n"
 
186
        ) );
 
187
 
 
188
  // Build the table's rows here
 
189
  QString dynamicPart;
 
190
 
 
191
 
 
192
  if ( !internalLoading ) {
 
193
    KABC::Picture pic = addr.photo();
 
194
    if ( pic.isIntern() && !pic.data().isNull() ) {
 
195
      image = pixmapAsDataUrl( QPixmap::fromImage( pic.data() ) );
 
196
    } else if ( !pic.url().isEmpty() ) {
 
197
      image = (pic.url().startsWith( "http://" ) || pic.url().startsWith( "https://" ) ? pic.url() : "http://" + pic.url());
 
198
    } else {
 
199
      image = "file:" + KIconLoader::global()->iconPath( "x-office-contact", KIconLoader::Desktop );
 
200
    }
 
201
  }
 
202
 
 
203
  if ( fieldMask & BirthdayFields ) {
 
204
    QDate date = addr.birthday().date();
 
205
 
 
206
    if ( date.isValid() )
 
207
      dynamicPart += rowFmtStr
 
208
        .arg( KABC::Addressee::birthdayLabel() )
 
209
        .arg( KGlobal::locale()->formatDate( date, KLocale::ShortDate ) );
 
210
  }
 
211
 
 
212
  if ( fieldMask & PhoneFields ) {
 
213
    const KABC::PhoneNumber::List phones = addr.phoneNumbers();
 
214
    KABC::PhoneNumber::List::ConstIterator phoneIt;
 
215
    for ( phoneIt = phones.constBegin(); phoneIt != phones.constEnd(); ++phoneIt ) {
 
216
      QString number = Qt::escape( (*phoneIt).number() );
 
217
 
 
218
      QString url;
 
219
      if ( (*phoneIt).type() & KABC::PhoneNumber::Fax )
 
220
        url = QString::fromLatin1( "fax:" ) + number;
 
221
      else
 
222
        url = QString::fromLatin1( "phone:" ) + number;
 
223
 
 
224
      if ( linkMask & PhoneLinks ) {
 
225
        QString smsURL;
 
226
        if ( (*phoneIt).type() & KABC::PhoneNumber::Cell )
 
227
          smsURL = QString(" (<a href=\"sms:%1\">%2</a>)" ).arg( number ).arg( i18n( "SMS") );
 
228
 
 
229
        dynamicPart += rowFmtStr
 
230
          .arg( (*phoneIt).typeLabel().replace( " ", "&nbsp;" ) )
 
231
          .arg( QString::fromLatin1( "<a href=\"%1\">%2</a>%3" ).arg( url ).arg( number ).arg( smsURL ) );
 
232
      } else {
 
233
        dynamicPart += rowFmtStr
 
234
          .arg( (*phoneIt).typeLabel().replace( " ", "&nbsp;" ) )
 
235
          .arg( number );
 
236
      }
 
237
    }
 
238
  }
 
239
 
 
240
  if ( fieldMask & EmailFields ) {
 
241
    const QStringList emails = addr.emails();
 
242
    QStringList::ConstIterator emailIt;
 
243
    QString type = i18n( "Email" );
 
244
    for ( emailIt = emails.constBegin(); emailIt != emails.constEnd(); ++emailIt ) {
 
245
      QByteArray fullEmail = KUrl::toPercentEncoding( addr.fullEmail( *emailIt ) );
 
246
 
 
247
      if ( linkMask & EmailLinks ) {
 
248
        dynamicPart += rowFmtStr.arg( type )
 
249
          .arg( QString::fromLatin1( "<a href=\"mailto:%1\">%2</a>" )
 
250
          .arg( fullEmail, Qt::escape( *emailIt ) ) );
 
251
      } else {
 
252
        dynamicPart += rowFmtStr.arg( type ).arg( *emailIt );
 
253
      }
 
254
    }
 
255
  }
 
256
 
 
257
  if ( fieldMask & URLFields ) {
 
258
    if ( !addr.url().url().isEmpty() ) {
 
259
      QString url;
 
260
      if ( linkMask & URLLinks ) {
 
261
        url = (addr.url().url().startsWith( "http://" ) || addr.url().url().startsWith( "https://" ) ? addr.url().url() :
 
262
          "http://" + addr.url().url());
 
263
        url = KStringHandler::tagUrls( url );
 
264
      } else {
 
265
        url = addr.url().url();
 
266
      }
 
267
      dynamicPart += rowFmtStr.arg( i18n("Homepage") ).arg( url );
 
268
    }
 
269
 
 
270
    QString blog = addr.custom( "KADDRESSBOOK", "BlogFeed" );
 
271
    if ( !blog.isEmpty() ) {
 
272
      if ( linkMask & URLLinks ) {
 
273
        blog = KStringHandler::tagUrls( blog );
 
274
      }
 
275
      dynamicPart += rowFmtStr.arg( i18n("Blog Feed") ).arg( blog );
 
276
    }
 
277
  }
 
278
 
 
279
  if ( fieldMask & AddressFields ) {
 
280
    const KABC::Address::List addresses = addr.addresses();
 
281
    KABC::Address::List::ConstIterator addrIt;
 
282
    for ( addrIt = addresses.constBegin(); addrIt != addresses.constEnd(); ++addrIt ) {
 
283
      if ( (*addrIt).label().isEmpty() ) {
 
284
        QString formattedAddress;
 
285
 
 
286
        formattedAddress = Qt::escape( (*addrIt).formattedAddress().trimmed() );
 
287
 
 
288
        formattedAddress = formattedAddress.replace( '\n', "<br>" );
 
289
 
 
290
        QString link = "<a href=\"addr:" + (*addrIt).id() + "\">" +
 
291
                       formattedAddress + "</a>";
 
292
 
 
293
        if ( linkMask & AddressLinks ) {
 
294
          dynamicPart += rowFmtStr
 
295
            .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
 
296
            .arg( link );
 
297
        } else {
 
298
          dynamicPart += rowFmtStr
 
299
            .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
 
300
            .arg( formattedAddress );
 
301
        }
 
302
      } else {
 
303
        QString link = "<a href=\"addr:" + (*addrIt).id() + "\">" +
 
304
                       (*addrIt).label().replace( '\n', "<br>" ) + "</a>";
 
305
 
 
306
        if ( linkMask & AddressLinks ) {
 
307
          dynamicPart += rowFmtStr
 
308
            .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
 
309
            .arg( link );
 
310
        } else {
 
311
          dynamicPart += rowFmtStr
 
312
            .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
 
313
            .arg( (*addrIt).label().replace( '\n', "<br>" ) );
 
314
        }
 
315
      }
 
316
    }
 
317
  }
 
318
 
 
319
  QString notes;
 
320
  if ( !addr.note().isEmpty() ) {
 
321
    // @STYLE@ - substitute the cell style in first, and append
 
322
    // the data afterwards (keeps us safe from possible % signs
 
323
    // in either one).
 
324
    notes = Qt::escape( addr.note() );
 
325
    notes = rowFmtStr.arg( i18n( "Notes" ) ).arg( notes.replace( '\n', "<br>" ) ) ;
 
326
  }
 
327
 
 
328
  QString customData;
 
329
  if ( fieldMask & CustomFields ) {
 
330
    static QMap<QString, QString> titleMap;
 
331
    if ( titleMap.isEmpty() ) {
 
332
      titleMap.insert( "Department", i18n( "Department" ) );
 
333
      titleMap.insert( "Profession", i18n( "Profession" ) );
 
334
      titleMap.insert( "AssistantsName", i18n( "Assistant's Name" ) );
 
335
      titleMap.insert( "ManagersName", i18n( "Manager's Name" ) );
 
336
      titleMap.insert( "SpousesName", i18nc( "Wife/Husband/...", "Partner's Name" ) );
 
337
      titleMap.insert( "Office", i18n( "Office" ) );
 
338
      titleMap.insert( "IMAddress", i18n( "IM Address" ) );
 
339
      titleMap.insert( "Anniversary", i18n( "Anniversary" ) );
 
340
    }
 
341
 
 
342
    if ( !addr.customs().empty() ) {
 
343
      QStringList customs = addr.customs();
 
344
      QStringList::Iterator it( customs.begin() );
 
345
      const QStringList::Iterator endIt( customs.end() );
 
346
      for ( ; it != endIt; ++it ) {
 
347
        QString customEntry = *it;
 
348
        if ( customEntry.startsWith ( "KADDRESSBOOK-" ) ) {
 
349
          customEntry.remove( "KADDRESSBOOK-X-" );
 
350
          customEntry.remove( "KADDRESSBOOK-" );
 
351
 
 
352
          int pos = customEntry.indexOf( ':' );
 
353
          QString key = customEntry.left( pos );
 
354
          const QString value = customEntry.mid( pos + 1 );
 
355
 
 
356
          // blog and im address are handled separated
 
357
          if ( key == "BlogFeed" || key == "IMAddress" )
 
358
            continue;
 
359
 
 
360
          const QMap<QString, QString>::ConstIterator keyIt = titleMap.constFind( key );
 
361
          if ( keyIt != titleMap.constEnd() )
 
362
            key = keyIt.value();
 
363
 
 
364
          customData += rowFmtStr.arg( key ).arg( Qt::escape( value ) ) ;
 
365
        }
 
366
      }
 
367
    }
 
368
  }
 
369
 
 
370
  QString name( Qt::escape( addr.realName() ) );
 
371
  QString role( Qt::escape( addr.role() ) );
 
372
  QString organization( Qt::escape( addr.organization() ) );
 
373
 
 
374
  if ( fieldMask & IMFields ) {
 
375
 
 
376
    const QString imAddress = addr.custom( "KADDRESSBOOK", "X-IMAddress" );
 
377
    if ( !imAddress.isEmpty() ) {
 
378
      customData += rowFmtStr.arg( i18n( "IM Address" ) ).arg( Qt::escape( imAddress ) ) ;
 
379
    }
 
380
 
 
381
/*
 
382
    if ( proxy ) {
 
383
      if ( proxy->isPresent( addr.uid() ) && proxy->presenceNumeric( addr.uid() ) > 0 ) {
 
384
        // set image source to either a QMimeSourceFactory key or a data:/ URL
 
385
        QString imgSrc = pixmapAsDataUrl( proxy->presenceIcon( addr.uid() ) );
 
386
 
 
387
        // make the status a link, if required
 
388
        QString imStatus;
 
389
        if ( linkMask & IMLinks )
 
390
          imStatus = QString::fromLatin1( "<a href=\"im:\"><img src=\"%1\"> (%2)</a>" );
 
391
        else
 
392
          imStatus = QString::fromLatin1( "<img src=\"%1\"> (%2)" );
 
393
 
 
394
        // append our status to the rest of the dynamic part of the addressee
 
395
        dynamicPart += rowFmtStr
 
396
                .arg( i18n( "Presence" ) )
 
397
                .arg( imStatus
 
398
                          .arg( imgSrc )
 
399
                          .arg( proxy->presenceString( addr.uid() ) )
 
400
                    );
 
401
      }
 
402
    }
 
403
*/
 
404
  }
 
405
 
 
406
  // @STYLE@ - construct the string by parts, substituting in
 
407
  // the styles first. There are lots of appends, but we need to
 
408
  // do it this way to avoid cases where the substituted string
 
409
  // contains %1 and the like.
 
410
  //
 
411
  QString strAddr = QString::fromLatin1(
 
412
    "<div align=\"center\">"
 
413
    "<table cellpadding=\"1\" cellspacing=\"0\" %1>"
 
414
    "<tr>").arg(tableStyle);
 
415
 
 
416
  strAddr.append( QString::fromLatin1(
 
417
    "<td align=\"right\" valign=\"top\" width=\"30%\" rowspan=\"3\" %2>")
 
418
    .arg( cellStyle ) );
 
419
  strAddr.append( QString::fromLatin1(
 
420
    "<img src=\"%1\" width=\"75\" vspace=\"1\">" // image
 
421
    "</td>")
 
422
    .arg( image ) );
 
423
  strAddr.append( QString::fromLatin1(
 
424
    "<td align=\"left\" width=\"70%\" %2>")
 
425
    .arg( cellStyle2 ) );
 
426
  strAddr.append( QString::fromLatin1(
 
427
    "<font size=\"+2\"><b>%2</b></font></td>"  // name
 
428
    "</tr>")
 
429
    .arg( name ) );
 
430
  strAddr.append( QString::fromLatin1(
 
431
    "<tr>"
 
432
    "<td align=\"left\" width=\"70%\" %2>")
 
433
    .arg( cellStyle2 ) );
 
434
  strAddr.append( QString::fromLatin1(
 
435
    "%3</td>"  // role
 
436
    "</tr>")
 
437
    .arg( role ) );
 
438
  strAddr.append( QString::fromLatin1(
 
439
    "<tr>"
 
440
    "<td align=\"left\" width=\"70%\" %2>")
 
441
    .arg( cellStyle2 ) );
 
442
  strAddr.append( QString::fromLatin1(
 
443
    "%4</td>"  // organization
 
444
    "</tr>")
 
445
    .arg( organization ) );
 
446
  strAddr.append( QString::fromLatin1(
 
447
    "<tr><td %2>")
 
448
    .arg( cellStyle ) );
 
449
  strAddr.append( QString::fromLatin1(
 
450
    "&nbsp;</td><td %2>&nbsp;</td></tr>")
 
451
    .arg( cellStyle2 ) );
 
452
  strAddr.append( dynamicPart );
 
453
  strAddr.append( notes );
 
454
  strAddr.append( customData );
 
455
  strAddr.append( QString::fromLatin1( "</table></div>\n" ) );
 
456
 
 
457
  if ( addr.resource() ) {
 
458
    QString addrBookName = addr.resource()->resourceName();
 
459
    KABC::ResourceABC *r = dynamic_cast<KABC::ResourceABC*>( addr.resource() );
 
460
    if ( r && !r->subresources().isEmpty() ) {
 
461
      const QString subRes = r->uidToResourceMap()[ addr.uid() ];
 
462
      const QString label = r->subresourceLabel( subRes );
 
463
      if ( !label.isEmpty() )
 
464
        addrBookName = label;
 
465
    }
 
466
    strAddr.append( i18n( "<p><b>Address book</b>: %1</p>", addrBookName ) );
 
467
  }
 
468
  return strAddr;
 
469
}
 
470
 
 
471
QString AddresseeView::pixmapAsDataUrl( const QPixmap& pixmap )
 
472
{
 
473
  QByteArray ba;
 
474
  QBuffer buffer( &ba, 0 );
 
475
  buffer.open( QIODevice::WriteOnly );
 
476
  pixmap.save( &buffer, "PNG" );
 
477
  QString encoded( "data:image/png;base64," );
 
478
  encoded.append( ba.toBase64() );
 
479
  return encoded;
 
480
}
 
481
 
 
482
void AddresseeView::updateView()
 
483
{
 
484
  // clear view
 
485
  setPlainText( QString() );
 
486
 
 
487
  if ( mAddressee.isEmpty() )
 
488
    return;
 
489
 
 
490
  if ( mImageJob ) {
 
491
    mImageJob->kill();
 
492
    mImageJob = 0;
 
493
 
 
494
    mImageData.truncate( 0 );
 
495
  }
 
496
 
 
497
  int fieldMask = NoFields;
 
498
  if ( mActionShowBirthday->isChecked() )
 
499
    fieldMask |= ( FieldMask )BirthdayFields;
 
500
  if ( mActionShowAddresses->isChecked() )
 
501
    fieldMask |= AddressFields;
 
502
  if ( mActionShowEmails->isChecked() )
 
503
    fieldMask |= EmailFields;
 
504
  if ( mActionShowPhones->isChecked() )
 
505
    fieldMask |= PhoneFields;
 
506
  if ( mActionShowURLs->isChecked() )
 
507
    fieldMask |= URLFields;
 
508
  if ( mActionShowIMAddresses->isChecked() )
 
509
    fieldMask |= IMFields;
 
510
  if ( mActionShowCustomFields->isChecked() )
 
511
    fieldMask |= CustomFields;
 
512
 
 
513
  QString strAddr = vCardAsHTML( mAddressee, mKIMProxy, (LinkMask)mLinkMask,
 
514
                                 true, (FieldMask)fieldMask );
 
515
 
 
516
  strAddr = QString::fromLatin1(
 
517
    "<html>"
 
518
    "<body text=\"%1\" bgcolor=\"%2\">" // text and background color
 
519
    "%3" // dynamic part
 
520
    "</body>"
 
521
    "</html>" )
 
522
     .arg( KColorScheme( QPalette::Active, KColorScheme::View ).foreground().color().name() )
 
523
     .arg( KColorScheme( QPalette::Active, KColorScheme::View ).background().color().name() )
 
524
     .arg( strAddr );
 
525
 
 
526
  QString imageURL = QString( "contact_%1_image" ).arg( mAddressee.uid() );
 
527
 
 
528
  KABC::Picture picture = mAddressee.photo();
 
529
  if ( picture.isIntern() && !picture.data().isNull() )
 
530
    document()->addResource( QTextDocument::ImageResource, imageURL, picture.data() );
 
531
  else {
 
532
    if ( !picture.url().isEmpty() ) {
 
533
      if ( mImageData.count() > 0 )
 
534
        document()->addResource( QTextDocument::ImageResource, imageURL, QImage::fromData( mImageData ) );
 
535
      else {
 
536
        mImageJob = KIO::get( KUrl( picture.url() ), KIO::NoReload, KIO::HideProgressInfo );
 
537
        connect( mImageJob, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
 
538
                 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
 
539
        connect( mImageJob, SIGNAL( result( KJob* ) ),
 
540
                 this, SLOT( result( KJob* ) ) );
 
541
      }
 
542
    } else {
 
543
      document()->addResource( QTextDocument::ImageResource, imageURL, KIcon( "x-office-contact" ).pixmap( 128, 128 ) );
 
544
    }
 
545
  }
 
546
 
 
547
  // at last display it...
 
548
  setHtml( strAddr );
 
549
}
 
550
 
 
551
KABC::Addressee AddresseeView::addressee() const
 
552
{
 
553
  return mAddressee;
 
554
}
 
555
 
 
556
void AddresseeView::urlClicked( const QString &url )
 
557
{
 
558
  KToolInvocation::invokeBrowser( url );
 
559
}
 
560
 
 
561
void AddresseeView::emailClicked( const QString &email )
 
562
{
 
563
  if ( email.startsWith( "mailto:" ) )
 
564
    KToolInvocation::invokeMailer( email.mid( 7 ), QString() );
 
565
  else
 
566
    KToolInvocation::invokeMailer( email, QString() );
 
567
}
 
568
 
 
569
void AddresseeView::phoneNumberClicked( const QString &number )
 
570
{
 
571
  KConfig _config( "kaddressbookrc" );
 
572
  KConfigGroup config(&_config, "General" );
 
573
  QString commandLine = config.readEntry( "PhoneHookApplication" );
 
574
 
 
575
  if ( commandLine.isEmpty() ) {
 
576
    KMessageBox::sorry( this, i18n( "There is no application set which could be executed. Please go to the settings dialog and configure one." ) );
 
577
    return;
 
578
  }
 
579
 
 
580
  commandLine.replace( "%N", number );
 
581
  KRun::runCommand( commandLine, topLevelWidget());
 
582
}
 
583
 
 
584
void AddresseeView::smsTextClicked( const QString &number )
 
585
{
 
586
  KConfig _config( "kaddressbookrc" );
 
587
  KConfigGroup config(&_config, "General" );
 
588
  QString commandLine = config.readEntry( "SMSHookApplication" );
 
589
 
 
590
  if ( commandLine.isEmpty() ) {
 
591
    KMessageBox::sorry( this, i18n( "There is no application set which could be executed. Please go to the settings dialog and configure one." ) );
 
592
    return;
 
593
  }
 
594
 
 
595
  SendSMSDialog dlg( mAddressee.realName(), this );
 
596
 
 
597
  if ( dlg.exec() )
 
598
    sendSMS ( number, dlg.text() );
 
599
}
 
600
 
 
601
void AddresseeView::sendSMS( const QString &number, const QString &text )
 
602
{
 
603
  KConfig _config( "kaddressbookrc" );
 
604
  KConfigGroup config(&_config, "General" );
 
605
  QString commandLine = config.readEntry( "SMSHookApplication" );
 
606
 
 
607
  KTemporaryFile file;
 
608
  file.setAutoRemove(false);
 
609
  file.open();
 
610
  QTextStream stream ( &file );
 
611
  stream << text;
 
612
  stream.flush();
 
613
 
 
614
  commandLine.replace( "%N", number );
 
615
  commandLine.replace( "%F", file.fileName() );
 
616
 
 
617
  KRun::runCommand( commandLine, topLevelWidget());
 
618
}
 
619
 
 
620
void AddresseeView::faxNumberClicked( const QString &number )
 
621
{
 
622
  KConfig _config( "kaddressbookrc" );
 
623
  KConfigGroup config(&_config, "General" );
 
624
  QString commandLine = config.readEntry( "FaxHookApplication", "kdeprintfax --phone %N" );
 
625
 
 
626
  if ( commandLine.isEmpty() ) {
 
627
    KMessageBox::sorry( this, i18n( "There is no application set which could be executed. Please go to the settings dialog and configure one." ) );
 
628
    return;
 
629
  }
 
630
 
 
631
  commandLine.replace( "%N", number );
 
632
  KRun::runCommand( commandLine, topLevelWidget());
 
633
}
 
634
 
 
635
void AddresseeView::imAddressClicked()
 
636
{
 
637
  // mKIMProxy->chatWithContact( mAddressee.uid() );
 
638
}
 
639
 
 
640
void AddresseeView::contextMenuEvent(QContextMenuEvent *e)
 
641
{
 
642
  QMenu *menu = new QMenu( this );
 
643
  menu->addAction( mActionShowBirthday );
 
644
  menu->addAction( mActionShowAddresses );
 
645
  menu->addAction( mActionShowEmails );
 
646
  menu->addAction( mActionShowPhones );
 
647
  menu->addAction( mActionShowURLs );
 
648
  menu->addAction( mActionShowIMAddresses );
 
649
  menu->addAction( mActionShowCustomFields );
 
650
  menu->exec(e->globalPos());
 
651
  delete menu;
 
652
}
 
653
 
 
654
void AddresseeView::slotMailClicked( const QString&, const QString &email )
 
655
{
 
656
  emailClicked( email );
 
657
}
 
658
 
 
659
void AddresseeView::slotUrlClicked( const QString &url )
 
660
{
 
661
  if ( url.startsWith( "phone:" ) )
 
662
    phoneNumberClicked( strippedNumber( url.mid( 6 ) ) );
 
663
  else if ( url.startsWith( "sms:" ) )
 
664
    smsTextClicked( strippedNumber( url.mid( 4 ) ) );
 
665
  else if ( url.startsWith( "fax:" ) )
 
666
    faxNumberClicked( strippedNumber( url.mid( 4 ) ) );
 
667
  else if ( url.startsWith( "addr:" ) )
 
668
    emit addressClicked( url.mid( 5 ) );
 
669
  else if ( url.startsWith( "im:" ) )
 
670
    imAddressClicked();
 
671
  else
 
672
    urlClicked( url );
 
673
}
 
674
 
 
675
void AddresseeView::slotHighlighted( const QString &link )
 
676
{
 
677
  if ( link.startsWith( "mailto:" ) ) {
 
678
    QString email = link.mid( 7 );
 
679
 
 
680
    emit emailHighlighted( email );
 
681
    emit highlightedMessage( i18n( "Send mail to '%1'", email ) );
 
682
  } else if ( link.startsWith( "phone:" ) ) {
 
683
    QString number = link.mid( 6 );
 
684
 
 
685
    emit phoneNumberHighlighted( strippedNumber( number ) );
 
686
    emit highlightedMessage( i18n( "Call number %1", number ) );
 
687
  } else if ( link.startsWith( "fax:" ) ) {
 
688
    QString number = link.mid( 4 );
 
689
 
 
690
    emit faxNumberHighlighted( strippedNumber( number ) );
 
691
    emit highlightedMessage( i18n( "Send fax to %1", number ) );
 
692
  } else if ( link.startsWith( "addr:" ) ) {
 
693
    emit highlightedMessage( i18n( "Show address on map" ) );
 
694
  } else if ( link.startsWith( "sms:" ) ) {
 
695
    QString number = link.mid( 4 );
 
696
    emit highlightedMessage( i18n( "Send SMS to %1", number ) );
 
697
  } else if ( link.startsWith( "http:" ) || link.startsWith( "https:" ) ) {
 
698
    emit urlHighlighted( link );
 
699
    emit highlightedMessage( i18n( "Open URL %1", link ) );
 
700
  } else if ( link.startsWith( "im:" ) ) {
 
701
    emit highlightedMessage( i18n( "Chat with %1", mAddressee.realName() ) );
 
702
  } else
 
703
    emit highlightedMessage( "" );
 
704
}
 
705
 
 
706
void AddresseeView::slotPresenceChanged( const QString &uid )
 
707
{
 
708
  kDebug() <<" uid is:" << uid <<" mAddressee is:" << mAddressee.uid();
 
709
  if ( uid == mAddressee.uid() )
 
710
    updateView();
 
711
}
 
712
 
 
713
 
 
714
void AddresseeView::slotPresenceInfoExpired()
 
715
{
 
716
  updateView();
 
717
}
 
718
 
 
719
void AddresseeView::configChanged()
 
720
{
 
721
  save();
 
722
  updateView();
 
723
}
 
724
 
 
725
void AddresseeView::data( KIO::Job*, const QByteArray &d )
 
726
{
 
727
  unsigned int oldSize = mImageData.size();
 
728
  mImageData.resize( oldSize + d.size() );
 
729
  memcpy( mImageData.data() + oldSize, d.data(), d.size() );
 
730
}
 
731
 
 
732
void AddresseeView::result( KJob *job )
 
733
{
 
734
  mImageJob = 0;
 
735
 
 
736
  if ( job->error() )
 
737
    mImageData.truncate( 0 );
 
738
  else
 
739
    updateView();
 
740
}
 
741
 
 
742
void AddresseeView::load()
 
743
{
 
744
  KConfigGroup group( mConfig, "AddresseeViewSettings" );
 
745
  mActionShowBirthday->setChecked( group.readEntry( "ShowBirthday", false ) );
 
746
  mActionShowAddresses->setChecked( group.readEntry( "ShowAddresses", true ) );
 
747
  mActionShowEmails->setChecked( group.readEntry( "ShowEmails", true ) );
 
748
  mActionShowPhones->setChecked( group.readEntry( "ShowPhones", true ) );
 
749
  mActionShowURLs->setChecked( group.readEntry( "ShowURLs", true ) );
 
750
  mActionShowIMAddresses->setChecked( group.readEntry( "ShowIMAddresses", false ) );
 
751
  mActionShowCustomFields->setChecked( group.readEntry( "ShowCustomFields", false ) );
 
752
}
 
753
 
 
754
void AddresseeView::save()
 
755
{
 
756
  KConfigGroup group( mConfig, "AddresseeViewSettings" );
 
757
  group.writeEntry( "ShowBirthday", mActionShowBirthday->isChecked() );
 
758
  group.writeEntry( "ShowAddresses", mActionShowAddresses->isChecked() );
 
759
  group.writeEntry( "ShowEmails", mActionShowEmails->isChecked() );
 
760
  group.writeEntry( "ShowPhones", mActionShowPhones->isChecked() );
 
761
  group.writeEntry( "ShowURLs", mActionShowURLs->isChecked() );
 
762
  group.writeEntry( "ShowIMAddresses", mActionShowIMAddresses->isChecked() );
 
763
  group.writeEntry( "ShowCustomFields", mActionShowCustomFields->isChecked() );
 
764
  mConfig->sync();
 
765
}
 
766
 
 
767
QString AddresseeView::strippedNumber( const QString &number )
 
768
{
 
769
  QString retval;
 
770
 
 
771
  for ( int i = 0; i < number.length(); ++i ) {
 
772
    QChar c = number[ i ];
 
773
    if ( c.isDigit() || c == '*' || c == '#' || (c == '+' && i == 0) )
 
774
      retval.append( c );
 
775
  }
 
776
 
 
777
  return retval;
 
778
}
 
779
 
 
780
#include "addresseeview.moc"