libtdepim

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