libkdepim

addresseeview.cpp

00001 /*
00002     This file is part of libkdepim.
00003 
00004     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public 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
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <qbuffer.h>
00023 #include <qimage.h>
00024 #include <qpopupmenu.h>
00025 #include <qurl.h>
00026 
00027 #include <kabc/address.h>
00028 #include <kabc/addressee.h>
00029 #include <kabc/phonenumber.h>
00030 #include <kactionclasses.h>
00031 #include <kapplication.h>
00032 #include <kconfig.h>
00033 #include <kglobal.h>
00034 #include <kglobalsettings.h>
00035 #include <kiconloader.h>
00036 #include <kio/job.h>
00037 #include <klocale.h>
00038 #include <kmdcodec.h>
00039 #include <kmessagebox.h>
00040 #include <krun.h>
00041 #include <kstringhandler.h>
00042 #include <ktempfile.h>
00043 
00044 #include <kdebug.h>
00045 
00046 #include "addresseeview.h"
00047 #include "sendsmsdialog.h"
00048 
00049 using namespace KPIM;
00050 
00051 AddresseeView::AddresseeView( QWidget *parent, const char *name,
00052                               KConfig *config )
00053   : KTextBrowser( parent, name ), mDefaultConfig( false ), mImageJob( 0 ),
00054     mLinkMask( AddressLinks | EmailLinks | PhoneLinks | URLLinks | IMLinks | CustomFields )
00055 {
00056   setWrapPolicy( QTextEdit::AtWordBoundary );
00057   setLinkUnderline( false );
00058   setVScrollBarMode( QScrollView::AlwaysOff );
00059   setHScrollBarMode( QScrollView::AlwaysOff );
00060 
00061   QStyleSheet *sheet = styleSheet();
00062   QStyleSheetItem *link = sheet->item( "a" );
00063   link->setColor( KGlobalSettings::linkColor() );
00064 
00065   connect( this, SIGNAL( mailClick( const QString&, const QString& ) ),
00066            this, SLOT( slotMailClicked( const QString&, const QString& ) ) );
00067   connect( this, SIGNAL( urlClick( const QString& ) ),
00068            this, SLOT( slotUrlClicked( const QString& ) ) );
00069   connect( this, SIGNAL( highlighted( const QString& ) ),
00070            this, SLOT( slotHighlighted( const QString& ) ) );
00071 
00072   setNotifyClick( true );
00073 
00074   mActionShowBirthday = new KToggleAction( i18n( "Show Birthday" ) );
00075   mActionShowBirthday->setCheckedState( i18n( "Hide Birthday" ) );
00076   mActionShowAddresses = new KToggleAction( i18n( "Show Postal Addresses" ) );
00077   mActionShowAddresses->setCheckedState( i18n( "Hide Postal Addresses" ) );
00078   mActionShowEmails = new KToggleAction( i18n( "Show Email Addresses" ) );
00079   mActionShowEmails->setCheckedState( i18n( "Hide Email Addresses" ) );
00080   mActionShowPhones = new KToggleAction( i18n( "Show Telephone Numbers" ) );
00081   mActionShowPhones->setCheckedState( i18n( "Hide Telephone Numbers" ) );
00082   mActionShowURLs = new KToggleAction( i18n( "Show Web Pages (URLs)" ) );
00083   mActionShowURLs->setCheckedState( i18n( "Hide Web Pages (URLs)" ) );
00084   mActionShowIMAddresses = new KToggleAction( i18n( "Show Instant Messaging Addresses" ) );
00085   mActionShowIMAddresses->setCheckedState( i18n( "Hide Instant Messaging Addresses" ) );
00086   mActionShowCustomFields = new KToggleAction( i18n( "Show Custom Fields" ) );
00087   mActionShowCustomFields->setCheckedState( i18n( "Hide Custom Fields" ) );
00088 
00089   connect( mActionShowBirthday, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00090   connect( mActionShowAddresses, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00091   connect( mActionShowEmails, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00092   connect( mActionShowPhones, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00093   connect( mActionShowURLs, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00094   connect( mActionShowIMAddresses, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00095   connect( mActionShowCustomFields, SIGNAL( toggled( bool ) ), SLOT( configChanged() ) );
00096 
00097   if ( !config ) {
00098     mConfig = new KConfig( "kaddressbookrc" );
00099     mDefaultConfig = true;
00100   } else
00101     mConfig = config;
00102 
00103   load();
00104 
00105   // set up IMProxy to display contacts' IM presence and make connections to keep the display live
00106   mKIMProxy = ::KIMProxy::instance( kapp->dcopClient() );
00107   connect( mKIMProxy, SIGNAL( sigContactPresenceChanged( const QString& ) ),
00108            this, SLOT( slotPresenceChanged( const QString& ) ) );
00109   connect( mKIMProxy, SIGNAL( sigPresenceInfoExpired() ),
00110            this, SLOT( slotPresenceInfoExpired() ) );
00111 }
00112 
00113 AddresseeView::~AddresseeView()
00114 {
00115   if ( mDefaultConfig )
00116     delete mConfig;
00117   mConfig = 0;
00118 
00119   delete mActionShowBirthday;
00120   delete mActionShowAddresses;
00121   delete mActionShowEmails;
00122   delete mActionShowPhones;
00123   delete mActionShowURLs;
00124   delete mActionShowIMAddresses;
00125   delete mActionShowCustomFields;
00126 
00127   mKIMProxy = 0;
00128 }
00129 
00130 void AddresseeView::setAddressee( const KABC::Addressee& addr )
00131 {
00132   mAddressee = addr;
00133 
00134   if ( mImageJob ) {
00135     mImageJob->kill();
00136     mImageJob = 0;
00137   }
00138 
00139   mImageData.truncate( 0 );
00140 
00141   updateView();
00142 }
00143 
00144 void AddresseeView::enableLinks( int linkMask )
00145 {
00146   mLinkMask = linkMask;
00147 }
00148 
00149 QString AddresseeView::vCardAsHTML( const KABC::Addressee& addr, ::KIMProxy *proxy, LinkMask linkMask,
00150                                     bool internalLoading, FieldMask fieldMask )
00151 {
00152   QString image = QString( "contact_%1_image" ).arg( addr.uid() );
00153 
00154   // Style strings from Gentix; this is just an initial version.
00155   //
00156   // These will be substituted into various HTML strings with .arg().
00157   // Search for @STYLE@ to find where. Note how we use %1 as a
00158   // placeholder where we fill in something else (in this case,
00159   // the global background color).
00160   //
00161   QString backgroundColor = KGlobalSettings::alternateBackgroundColor().name();
00162   QString cellStyle = QString::fromLatin1(
00163         "style=\""
00164         "padding-right: 2px; "
00165         "border-right: #000 dashed 1px; "
00166         "background: %1;\"").arg(backgroundColor);
00167   QString backgroundColor2 = KGlobalSettings::baseColor().name();
00168   QString cellStyle2 = QString::fromLatin1(
00169         "style=\""
00170         "padding-left: 2px; "
00171         "background: %1;\"").arg(backgroundColor2);
00172   QString tableStyle = QString::fromLatin1(
00173         "style=\""
00174         "border: solid 1px; "
00175         "margin: 0em;\"");
00176 
00177   // We'll be building a table to display the vCard in.
00178   // Each row of the table will be built using this string for its HTML.
00179   //
00180   QString rowFmtStr = QString::fromLatin1(
00181         "<tr>"
00182         "<td align=\"right\" valign=\"top\" width=\"30%\" "); // Tag unclosed
00183   rowFmtStr.append( cellStyle );
00184   rowFmtStr.append( QString::fromLatin1(
00185     ">" // Close tag
00186         "<b>%1</b>"
00187         "</td>"
00188         "<td align=\"left\" valign=\"top\" width=\"70%\" ") ); // Tag unclosed
00189   rowFmtStr.append( cellStyle2 );
00190   rowFmtStr.append( QString::fromLatin1(
00191     ">" // Close tag
00192         "%2"
00193         "</td>"
00194         "</tr>\n"
00195         ) );
00196 
00197   // Build the table's rows here
00198   QString dynamicPart;
00199 
00200 
00201   if ( !internalLoading ) {
00202     KABC::Picture pic = addr.photo();
00203     if ( pic.isIntern() && !pic.data().isNull() ) {
00204       image = pixmapAsDataUrl( pic.data() );
00205     } else if ( !pic.url().isEmpty() ) {
00206       image = (pic.url().startsWith( "http://" ) || pic.url().startsWith( "https://" ) ? pic.url() : "http://" + pic.url());
00207     } else {
00208       image = "file:" + KGlobal::iconLoader()->iconPath( "personal", KIcon::Desktop );
00209     }
00210   }
00211 
00212   if ( fieldMask & BirthdayFields ) {
00213     QDate date = addr.birthday().date();
00214 
00215     if ( date.isValid() )
00216       dynamicPart += rowFmtStr
00217         .arg( KABC::Addressee::birthdayLabel() )
00218         .arg( KGlobal::locale()->formatDate( date, true ) );
00219   }
00220 
00221   if ( fieldMask & PhoneFields ) {
00222     KABC::PhoneNumber::List phones = addr.phoneNumbers();
00223     KABC::PhoneNumber::List::ConstIterator phoneIt;
00224     for ( phoneIt = phones.begin(); phoneIt != phones.end(); ++phoneIt ) {
00225       QString number = (*phoneIt).number();
00226 
00227       QString url;
00228       if ( (*phoneIt).type() & KABC::PhoneNumber::Fax )
00229         url = QString::fromLatin1( "fax:" ) + number;
00230       else
00231         url = QString::fromLatin1( "phone:" ) + number;
00232 
00233       if ( linkMask & PhoneLinks ) {
00234         QString smsURL;
00235         if ( (*phoneIt).type() & KABC::PhoneNumber::Cell )
00236           smsURL = QString(" (<a href=\"sms:%1\">%2</a>)" ).arg( number ).arg( i18n( "SMS") );
00237 
00238         dynamicPart += rowFmtStr
00239           .arg( KABC::PhoneNumber::typeLabel( (*phoneIt).type() ).replace( " ", "&nbsp;" ) )
00240           .arg( QString::fromLatin1( "<a href=\"%1\">%2</a>%3" ).arg( url ).arg( number ).arg( smsURL ) );
00241       } else {
00242         dynamicPart += rowFmtStr
00243           .arg( KABC::PhoneNumber::typeLabel( (*phoneIt).type() ).replace( " ", "&nbsp;" ) )
00244           .arg( number );
00245       }
00246     }
00247   }
00248 
00249   if ( fieldMask & EmailFields ) {
00250     QStringList emails = addr.emails();
00251     QStringList::ConstIterator emailIt;
00252     QString type = i18n( "Email" );
00253     for ( emailIt = emails.begin(); emailIt != emails.end(); ++emailIt ) {
00254       QString fullEmail = addr.fullEmail( *emailIt );
00255       QUrl::encode( fullEmail );
00256 
00257       if ( linkMask & EmailLinks ) {
00258         dynamicPart += rowFmtStr.arg( type )
00259           .arg( QString::fromLatin1( "<a href=\"mailto:%1\">%2</a>" )
00260           .arg( fullEmail, *emailIt ) );
00261       } else {
00262         dynamicPart += rowFmtStr.arg( type ).arg( *emailIt );
00263       }
00264     }
00265   }
00266 
00267   if ( fieldMask & URLFields ) {
00268     if ( !addr.url().url().isEmpty() ) {
00269       QString url;
00270       if ( linkMask & URLLinks ) {
00271         url = (addr.url().url().startsWith( "http://" ) || addr.url().url().startsWith( "https://" ) ? addr.url().prettyURL() :
00272           "http://" + addr.url().prettyURL());
00273         url = KStringHandler::tagURLs( url );
00274       } else {
00275         url = addr.url().prettyURL();
00276       }
00277       dynamicPart += rowFmtStr.arg( i18n("Homepage") ).arg( url );
00278     }
00279 
00280     QString blog = addr.custom( "KADDRESSBOOK", "BlogFeed" );
00281     if ( !blog.isEmpty() ) {
00282       if ( linkMask & URLLinks ) {
00283         blog = KStringHandler::tagURLs( blog );
00284       }
00285       dynamicPart += rowFmtStr.arg( i18n("Blog Feed") ).arg( blog );
00286     }
00287   }
00288 
00289   if ( fieldMask & AddressFields ) {
00290     KABC::Address::List addresses = addr.addresses();
00291     KABC::Address::List::ConstIterator addrIt;
00292     for ( addrIt = addresses.begin(); addrIt != addresses.end(); ++addrIt ) {
00293       if ( (*addrIt).label().isEmpty() ) {
00294         QString formattedAddress;
00295 
00296 #if KDE_IS_VERSION(3,1,90)
00297         formattedAddress = (*addrIt).formattedAddress().stripWhiteSpace();
00298 #else
00299         if ( !(*addrIt).street().isEmpty() )
00300           formattedAddress += (*addrIt).street() + "\n";
00301 
00302         if ( !(*addrIt).postOfficeBox().isEmpty() )
00303           formattedAddress += (*addrIt).postOfficeBox() + "\n";
00304 
00305         formattedAddress += (*addrIt).locality() + QString::fromLatin1(" ") + (*addrIt).region();
00306 
00307         if ( !(*addrIt).postalCode().isEmpty() )
00308           formattedAddress += QString::fromLatin1(", ") + (*addrIt).postalCode();
00309 
00310         formattedAddress += "\n";
00311 
00312         if ( !(*addrIt).country().isEmpty() )
00313           formattedAddress += (*addrIt).country() + "\n";
00314 
00315         formattedAddress += (*addrIt).extended();
00316 #endif
00317 
00318         formattedAddress = formattedAddress.replace( '\n', "<br>" );
00319 
00320         QString link = "<a href=\"addr:" + (*addrIt).id() + "\">" +
00321                        formattedAddress + "</a>";
00322 
00323         if ( linkMask & AddressLinks ) {
00324           dynamicPart += rowFmtStr
00325             .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
00326             .arg( link );
00327         } else {
00328           dynamicPart += rowFmtStr
00329             .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
00330             .arg( formattedAddress );
00331         }
00332       } else {
00333         QString link = "<a href=\"addr:" + (*addrIt).id() + "\">" +
00334                        (*addrIt).label().replace( '\n', "<br>" ) + "</a>";
00335 
00336         if ( linkMask & AddressLinks ) {
00337           dynamicPart += rowFmtStr
00338             .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
00339             .arg( link );
00340         } else {
00341           dynamicPart += rowFmtStr
00342             .arg( KABC::Address::typeLabel( (*addrIt).type() ) )
00343             .arg( (*addrIt).label().replace( '\n', "<br>" ) );
00344         }
00345       }
00346     }
00347   }
00348 
00349   QString notes;
00350   if ( !addr.note().isEmpty() ) {
00351     // @STYLE@ - substitute the cell style in first, and append
00352     // the data afterwards (keeps us safe from possible % signs
00353     // in either one).
00354     notes = rowFmtStr.arg( i18n( "Notes" ) ).arg( addr.note().replace( '\n', "<br>" ) ) ;
00355   }
00356 
00357   QString customData;
00358   if ( fieldMask & CustomFields ) {
00359     static QMap<QString, QString> titleMap;
00360     if ( titleMap.isEmpty() ) {
00361       titleMap.insert( "Department", i18n( "Department" ) );
00362       titleMap.insert( "Profession", i18n( "Profession" ) );
00363       titleMap.insert( "AssistantsName", i18n( "Assistant's Name" ) );
00364       titleMap.insert( "ManagersName", i18n( "Manager's Name" ) );
00365       titleMap.insert( "SpousesName", i18n( "Partner's Name" ) );
00366       titleMap.insert( "Office", i18n( "Office" ) );
00367       titleMap.insert( "Anniversary", i18n( "Anniversary" ) );
00368     }
00369 
00370     if ( !addr.customs().empty() ) {
00371       QStringList customs = addr.customs();
00372       QStringList::Iterator it( customs.begin() );
00373       const QStringList::Iterator endIt( customs.end() );
00374       for ( ; it != endIt; ++it ) {
00375         QString customEntry = *it;
00376         if ( customEntry.startsWith ( "KADDRESSBOOK-" ) ) {
00377           customEntry.remove( "KADDRESSBOOK-X-" );
00378           customEntry.remove( "KADDRESSBOOK-" );
00379 
00380           int pos = customEntry.find( ':' );
00381           QString key = customEntry.left( pos );
00382           const QString value = customEntry.mid( pos + 1 );
00383 
00384           // blog and im address is handled separated
00385           if ( key == "BlogFeed" || key == "IMAddress" )
00386             continue;
00387 
00388           const QMap<QString, QString>::ConstIterator keyIt = titleMap.find( key );
00389           if ( keyIt != titleMap.end() )
00390             key = keyIt.data();
00391 
00392           customData += rowFmtStr.arg( key ).arg( value ) ;
00393         }
00394       }
00395     }
00396   }
00397 
00398   QString name( addr.realName() );
00399   QString role( addr.role() );
00400   QString organization( addr.organization() );
00401 
00402   if ( fieldMask & IMFields ) {
00403 
00404     const QString imAddress = addr.custom( "KADDRESSBOOK", "X-IMAddress" );
00405     if ( !imAddress.isEmpty() ) {
00406       customData += rowFmtStr.arg( i18n( "IM Address" ) ).arg( imAddress ) ;
00407     }
00408 
00409     if ( proxy ) {
00410       if ( proxy->isPresent( addr.uid() ) && proxy->presenceNumeric( addr.uid() ) > 0 ) {
00411         // set image source to either a QMimeSourceFactory key or a data:/ URL
00412         QString imgSrc;
00413         if ( internalLoading ) {
00414           imgSrc = QString::fromLatin1( "im_status_%1_image").arg( addr.uid() );
00415           QMimeSourceFactory::defaultFactory()->setPixmap( imgSrc, proxy->presenceIcon( addr.uid() ) );
00416         } else
00417           imgSrc = pixmapAsDataUrl( proxy->presenceIcon( addr.uid() ) );
00418 
00419         // make the status a link, if required
00420         QString imStatus;
00421         if ( linkMask & IMLinks )
00422           imStatus = QString::fromLatin1( "<a href=\"im:\"><img src=\"%1\"> (%2)</a>" );
00423         else
00424           imStatus = QString::fromLatin1( "<img src=\"%1\"> (%2)" );
00425 
00426         // append our status to the rest of the dynamic part of the addressee
00427         dynamicPart += rowFmtStr
00428                 .arg( i18n( "Presence" ) )
00429                 .arg( imStatus
00430                           .arg( imgSrc )
00431                           .arg( proxy->presenceString( addr.uid() ) )
00432                     );
00433       }
00434     }
00435   }
00436 
00437   // @STYLE@ - construct the string by parts, substituting in
00438   // the styles first. There are lots of appends, but we need to
00439   // do it this way to avoid cases where the substituted string
00440   // contains %1 and the like.
00441   //
00442   QString strAddr = QString::fromLatin1(
00443     "<div align=\"center\">"
00444     "<table cellpadding=\"1\" cellspacing=\"0\" %1>"
00445     "<tr>").arg(tableStyle);
00446 
00447   strAddr.append( QString::fromLatin1(
00448     "<td align=\"right\" valign=\"top\" width=\"30%\" rowspan=\"3\" %2>")
00449     .arg( cellStyle ) );
00450   strAddr.append( QString::fromLatin1(
00451     "<img src=\"%1\" width=\"50\" vspace=\"1\">" // image
00452     "</td>")
00453     .arg( image ) );
00454   strAddr.append( QString::fromLatin1(
00455     "<td align=\"left\" width=\"70%\" %2>")
00456     .arg( cellStyle2 ) );
00457   strAddr.append( QString::fromLatin1(
00458     "<font size=\"+2\"><b>%2</b></font></td>"  // name
00459     "</tr>")
00460     .arg( name ) );
00461   strAddr.append( QString::fromLatin1(
00462     "<tr>"
00463     "<td align=\"left\" width=\"70%\" %2>")
00464     .arg( cellStyle2 ) );
00465   strAddr.append( QString::fromLatin1(
00466     "%3</td>"  // role
00467     "</tr>")
00468     .arg( role ) );
00469   strAddr.append( QString::fromLatin1(
00470     "<tr>"
00471     "<td align=\"left\" width=\"70%\" %2>")
00472     .arg( cellStyle2 ) );
00473   strAddr.append( QString::fromLatin1(
00474     "%4</td>"  // organization
00475     "</tr>")
00476     .arg( organization ) );
00477   strAddr.append( QString::fromLatin1(
00478     "<tr><td %2>")
00479     .arg( cellStyle ) );
00480   strAddr.append( QString::fromLatin1(
00481     "&nbsp;</td><td %2>&nbsp;</td></tr>")
00482     .arg( cellStyle2 ) );
00483   strAddr.append( dynamicPart );
00484   strAddr.append( notes );
00485   strAddr.append( customData );
00486   strAddr.append( QString::fromLatin1( "</table></div>\n" ) );
00487 
00488   return strAddr;
00489 }
00490 
00491 QString AddresseeView::pixmapAsDataUrl( const QPixmap& pixmap )
00492 {
00493   QByteArray ba;
00494   QBuffer buffer( ba );
00495   buffer.open( IO_WriteOnly );
00496   pixmap.save( &buffer, "PNG" );
00497   QString encoded( "data:image/png;base64," );
00498   encoded.append( KCodecs::base64Encode( ba ) );
00499   return encoded;
00500 }
00501 
00502 void AddresseeView::updateView()
00503 {
00504   // clear view
00505   setText( QString::null );
00506 
00507   if ( mAddressee.isEmpty() )
00508     return;
00509 
00510   if ( mImageJob ) {
00511     mImageJob->kill();
00512     mImageJob = 0;
00513 
00514     mImageData.truncate( 0 );
00515   }
00516 
00517   int fieldMask = NoFields;
00518   if ( mActionShowBirthday->isChecked() )
00519     fieldMask |= ( FieldMask )BirthdayFields;
00520   if ( mActionShowAddresses->isChecked() )
00521     fieldMask |= AddressFields;
00522   if ( mActionShowEmails->isChecked() )
00523     fieldMask |= EmailFields;
00524   if ( mActionShowPhones->isChecked() )
00525     fieldMask |= PhoneFields;
00526   if ( mActionShowURLs->isChecked() )
00527     fieldMask |= URLFields;
00528   if ( mActionShowIMAddresses->isChecked() )
00529     fieldMask |= IMFields;
00530   if ( mActionShowCustomFields->isChecked() )
00531     fieldMask |= CustomFields;
00532 
00533   QString strAddr = vCardAsHTML( mAddressee, mKIMProxy, (LinkMask)mLinkMask,
00534                                  true, (FieldMask)fieldMask );
00535 
00536   strAddr = QString::fromLatin1(
00537     "<html>"
00538     "<body text=\"%1\" bgcolor=\"%2\">" // text and background color
00539     "%3" // dynamic part
00540     "</body>"
00541     "</html>" )
00542      .arg( KGlobalSettings::textColor().name() )
00543      .arg( KGlobalSettings::baseColor().name() )
00544      .arg( strAddr );
00545 
00546   QString imageURL = QString( "contact_%1_image" ).arg( mAddressee.uid() );
00547 
00548   KABC::Picture picture = mAddressee.photo();
00549   if ( picture.isIntern() && !picture.data().isNull() )
00550     QMimeSourceFactory::defaultFactory()->setImage( imageURL, picture.data() );
00551   else {
00552     if ( !picture.url().isEmpty() ) {
00553       if ( mImageData.count() > 0 )
00554         QMimeSourceFactory::defaultFactory()->setImage( imageURL, mImageData );
00555       else {
00556         mImageJob = KIO::get( KURL( picture.url() ), false, false );
00557         connect( mImageJob, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00558                  this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00559         connect( mImageJob, SIGNAL( result( KIO::Job* ) ),
00560                  this, SLOT( result( KIO::Job* ) ) );
00561       }
00562     } else {
00563       QMimeSourceFactory::defaultFactory()->setPixmap( imageURL,
00564         KGlobal::iconLoader()->loadIcon( "personal", KIcon::Desktop, 128 ) );
00565     }
00566   }
00567 
00568   // at last display it...
00569   setText( strAddr );
00570 }
00571 
00572 KABC::Addressee AddresseeView::addressee() const
00573 {
00574   return mAddressee;
00575 }
00576 
00577 void AddresseeView::urlClicked( const QString &url )
00578 {
00579   kapp->invokeBrowser( url );
00580 }
00581 
00582 void AddresseeView::emailClicked( const QString &email )
00583 {
00584   if ( email.startsWith( "mailto:" ) )
00585     kapp->invokeMailer( email.mid( 7 ), QString::null );
00586   else
00587     kapp->invokeMailer( email, QString::null );
00588 }
00589 
00590 void AddresseeView::phoneNumberClicked( const QString &number )
00591 {
00592   KConfig config( "kaddressbookrc" );
00593   config.setGroup( "General" );
00594   QString commandLine = config.readEntry( "PhoneHookApplication" );
00595 
00596   if ( commandLine.isEmpty() ) {
00597     KMessageBox::sorry( this, i18n( "There is no application set which could be executed. Please go to the settings dialog and configure one." ) );
00598     return;
00599   }
00600 
00601   commandLine.replace( "%N", number );
00602   KRun::runCommand( commandLine );
00603 }
00604 
00605 void AddresseeView::smsTextClicked( const QString &number )
00606 {
00607   KConfig config( "kaddressbookrc" );
00608   config.setGroup( "General" );
00609   QString commandLine = config.readEntry( "SMSHookApplication" );
00610 
00611   if ( commandLine.isEmpty() ) {
00612     KMessageBox::sorry( this, i18n( "There is no application set which could be executed. Please go to the settings dialog and configure one." ) );
00613     return;
00614   }
00615 
00616   SendSMSDialog dlg( mAddressee.realName(), this );
00617 
00618   if ( dlg.exec() )
00619     sendSMS ( number, dlg.text() );
00620 }
00621 
00622 void AddresseeView::sendSMS( const QString &number, const QString &text )
00623 {
00624   KConfig config( "kaddressbookrc" );
00625   config.setGroup( "General" );
00626   QString commandLine = config.readEntry( "SMSHookApplication" );
00627 
00628   KTempFile file ;
00629   QTextStream* stream = file.textStream();
00630   *stream << text;
00631   file.close();
00632 
00633   commandLine.replace( "%N", number );
00634   commandLine.replace( "%F", file.name() );
00635 
00636   KRun::runCommand( commandLine );
00637 }
00638 
00639 void AddresseeView::faxNumberClicked( const QString &number )
00640 {
00641   KConfig config( "kaddressbookrc" );
00642   config.setGroup( "General" );
00643   QString commandLine = config.readEntry( "FaxHookApplication", "kdeprintfax --phone %N" );
00644 
00645   if ( commandLine.isEmpty() ) {
00646     KMessageBox::sorry( this, i18n( "There is no application set which could be executed. Please go to the settings dialog and configure one." ) );
00647     return;
00648   }
00649 
00650   commandLine.replace( "%N", number );
00651   KRun::runCommand( commandLine );
00652 }
00653 
00654 void AddresseeView::imAddressClicked()
00655 {
00656   mKIMProxy->chatWithContact( mAddressee.uid() );
00657 }
00658 
00659 QPopupMenu *AddresseeView::createPopupMenu( const QPoint& )
00660 {
00661   QPopupMenu *menu = new QPopupMenu( this );
00662   mActionShowBirthday->plug( menu );
00663   mActionShowAddresses->plug( menu );
00664   mActionShowEmails->plug( menu );
00665   mActionShowPhones->plug( menu );
00666   mActionShowURLs->plug( menu );
00667   mActionShowIMAddresses->plug( menu );
00668   mActionShowCustomFields->plug( menu );
00669 
00670   return menu;
00671 }
00672 
00673 void AddresseeView::slotMailClicked( const QString&, const QString &email )
00674 {
00675   emailClicked( email );
00676 }
00677 
00678 void AddresseeView::slotUrlClicked( const QString &url )
00679 {
00680   if ( url.startsWith( "phone:" ) )
00681     phoneNumberClicked( strippedNumber( url.mid( 8 ) ) );
00682   else if ( url.startsWith( "sms:" ) )
00683     smsTextClicked( strippedNumber( url.mid( 6 ) ) );
00684   else if ( url.startsWith( "fax:" ) )
00685     faxNumberClicked( strippedNumber( url.mid( 6 ) ) );
00686   else if ( url.startsWith( "addr:" ) )
00687     emit addressClicked( url.mid( 7 ) );
00688   else if ( url.startsWith( "im:" ) )
00689     imAddressClicked();
00690   else
00691     urlClicked( url );
00692 }
00693 
00694 void AddresseeView::slotHighlighted( const QString &link )
00695 {
00696   if ( link.startsWith( "mailto:" ) ) {
00697     QString email = link.mid( 7 );
00698 
00699     emit emailHighlighted( email );
00700     emit highlightedMessage( i18n( "Send mail to '%1'" ).arg( email ) );
00701   } else if ( link.startsWith( "phone:" ) ) {
00702     QString number = link.mid( 8 );
00703 
00704     emit phoneNumberHighlighted( strippedNumber( number ) );
00705     emit highlightedMessage( i18n( "Call number %1" ).arg( number ) );
00706   } else if ( link.startsWith( "fax:" ) ) {
00707     QString number = link.mid( 6 );
00708 
00709     emit faxNumberHighlighted( strippedNumber( number ) );
00710     emit highlightedMessage( i18n( "Send fax to %1" ).arg( number ) );
00711   } else if ( link.startsWith( "addr:" ) ) {
00712     emit highlightedMessage( i18n( "Show address on map" ) );
00713   } else if ( link.startsWith( "sms:" ) ) {
00714     QString number = link.mid( 6 );
00715     emit highlightedMessage( i18n( "Send SMS to %1" ).arg( number ) );
00716   } else if ( link.startsWith( "http:" ) || link.startsWith( "https:" ) ) {
00717     emit urlHighlighted( link );
00718     emit highlightedMessage( i18n( "Open URL %1" ).arg( link ) );
00719   } else if ( link.startsWith( "im:" ) ) {
00720     emit highlightedMessage( i18n( "Chat with %1" ).arg( mAddressee.realName() ) );
00721   } else
00722     emit highlightedMessage( "" );
00723 }
00724 
00725 void AddresseeView::slotPresenceChanged( const QString &uid )
00726 {
00727   kdDebug() << k_funcinfo << " uid is: " << uid << " mAddressee is: " << mAddressee.uid() << endl;
00728   if ( uid == mAddressee.uid() )
00729     updateView();
00730 }
00731 
00732 
00733 void AddresseeView::slotPresenceInfoExpired()
00734 {
00735   updateView();
00736 }
00737 
00738 void AddresseeView::configChanged()
00739 {
00740   save();
00741   updateView();
00742 }
00743 
00744 void AddresseeView::data( KIO::Job*, const QByteArray &d )
00745 {
00746   unsigned int oldSize = mImageData.size();
00747   mImageData.resize( oldSize + d.size() );
00748   memcpy( mImageData.data() + oldSize, d.data(), d.size() );
00749 }
00750 
00751 void AddresseeView::result( KIO::Job *job )
00752 {
00753   mImageJob = 0;
00754 
00755   if ( job->error() )
00756     mImageData.truncate( 0 );
00757   else
00758     updateView();
00759 }
00760 
00761 void AddresseeView::load()
00762 {
00763   mConfig->setGroup( "AddresseeViewSettings" );
00764   mActionShowBirthday->setChecked( mConfig->readBoolEntry( "ShowBirthday", false ) );
00765   mActionShowAddresses->setChecked( mConfig->readBoolEntry( "ShowAddresses", true ) );
00766   mActionShowEmails->setChecked( mConfig->readBoolEntry( "ShowEmails", true ) );
00767   mActionShowPhones->setChecked( mConfig->readBoolEntry( "ShowPhones", true ) );
00768   mActionShowURLs->setChecked( mConfig->readBoolEntry( "ShowURLs", true ) );
00769   mActionShowIMAddresses->setChecked( mConfig->readBoolEntry( "ShowIMAddresses", false ) );
00770   mActionShowCustomFields->setChecked( mConfig->readBoolEntry( "ShowCustomFields", false ) );
00771 }
00772 
00773 void AddresseeView::save()
00774 {
00775   mConfig->setGroup( "AddresseeViewSettings" );
00776   mConfig->writeEntry( "ShowBirthday", mActionShowBirthday->isChecked() );
00777   mConfig->writeEntry( "ShowAddresses", mActionShowAddresses->isChecked() );
00778   mConfig->writeEntry( "ShowEmails", mActionShowEmails->isChecked() );
00779   mConfig->writeEntry( "ShowPhones", mActionShowPhones->isChecked() );
00780   mConfig->writeEntry( "ShowURLs", mActionShowURLs->isChecked() );
00781   mConfig->writeEntry( "ShowIMAddresses", mActionShowIMAddresses->isChecked() );
00782   mConfig->writeEntry( "ShowCustomFields", mActionShowCustomFields->isChecked() );
00783   mConfig->sync();
00784 }
00785 
00786 QString AddresseeView::strippedNumber( const QString &number )
00787 {
00788   QString retval;
00789 
00790   for ( uint i = 0; i < number.length(); ++i ) {
00791     QChar c = number[ i ];
00792     if ( c.isDigit() || c == '*' || c == '#' || c == '+' && i == 0 )
00793       retval.append( c );
00794   }
00795 
00796   return retval;
00797 }
00798 
00799 #include "addresseeview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys