libtdepim

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