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