libkdepim

distributionlist.cpp

00001 #include "distributionlist.h"
00002 #include <kabc/addressbook.h>
00003 
00004 static const char* s_customFieldName = "DistributionList";
00005 
00006 KPIM::DistributionList::DistributionList()
00007  : KABC::Addressee()
00008 {
00009   // can't insert the custom entry here, we need to remain a null addressee
00010 }
00011 
00012 KPIM::DistributionList::DistributionList( const KABC::Addressee& addr )
00013  : KABC::Addressee( addr )
00014 {
00015 }
00016 
00017 void KPIM::DistributionList::setName( const TQString &name )
00018 {
00019   // We can't use Addressee::setName, the name isn't saved/loaded in the vcard (fixed in 3.4)
00020   Addressee::setFormattedName( name );
00021   // Also set family name, just in case this entry appears in the normal contacts list (e.g. old kaddressbook)
00022   Addressee::setFamilyName( name );
00023   // We're not an empty addressee anymore
00024   // Set the custom field to non-empty, so that isDistributionList works
00025   if ( custom( "KADDRESSBOOK", s_customFieldName ).isEmpty() )
00026     insertCustom( "KADDRESSBOOK", s_customFieldName, ";" );
00027 }
00028 
00029 // Helper function, to parse the contents of the custom field
00030 // Returns a list of { uid, email }
00031 typedef TQValueList<TQPair<TQString, TQString> > ParseList;
00032 static ParseList parseCustom( const TQString& str )
00033 {
00034   ParseList res;
00035   const TQStringList lst = TQStringList::split( ';', str );
00036   for( TQStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
00037     if ( (*it).isEmpty() )
00038       continue;
00039     // parse "uid,email"
00040     TQStringList helpList = TQStringList::split( ',', (*it), true );
00041     Q_ASSERT( !helpList.isEmpty() );
00042     if ( helpList.isEmpty() )
00043       continue;
00044     Q_ASSERT( helpList.count() < 3 ); // 1 or 2 items, but not more
00045     const TQString uid = helpList.first();
00046     const TQString email = helpList.last();
00047     res.append( tqMakePair( uid, email ) );
00048   }
00049   return res;
00050 }
00051 
00052 void KPIM::DistributionList::insertEntry( const Addressee& addr, const TQString& email )
00053 {
00054   // insertEntry will removeEntry(uid), but not with formattedName
00055   removeEntry( addr.formattedName(), email );
00056   insertEntry( addr.uid(), email );
00057 }
00058 
00059 void KPIM::DistributionList::insertEntry( const TQString& uid, const TQString& email )
00060 {
00061   Q_ASSERT( !email.isEmpty() || email.isNull() ); // hopefully never called with "", would lead to confusion
00062   removeEntry( uid, email ); // avoid duplicates
00063   TQString str = custom( "KADDRESSBOOK", s_customFieldName );
00064   // Assumption: UIDs don't contain ; nor ,
00065   str += ";" + uid + "," + email;
00066   insertCustom( "KADDRESSBOOK", s_customFieldName, str ); // replace old value
00067 }
00068 
00069 void KPIM::DistributionList::removeEntry( const Addressee& addr, const TQString& email )
00070 {
00071   removeEntry( addr.uid(), email );
00072   // Also remove entries with the full name as uid (for the kolab thing)
00073   removeEntry( addr.formattedName(), email );
00074 }
00075 
00076 void KPIM::DistributionList::removeEntry( const TQString& uid, const TQString& email )
00077 {
00078   Q_ASSERT( !email.isEmpty() || email.isNull() ); // hopefully never called with "", would lead to confusion
00079   ParseList parseList = parseCustom( custom( "KADDRESSBOOK", s_customFieldName ) );
00080   TQString str;
00081   for( ParseList::ConstIterator it = parseList.begin(); it != parseList.end(); ++it ) {
00082     const TQString thisUid = (*it).first;
00083     const TQString thisEmail = (*it).second;
00084     if ( thisUid == uid && thisEmail == email ) {
00085       continue; // remove that one
00086     }
00087     str += ";" + thisUid + "," + thisEmail;
00088   }
00089   if ( str.isEmpty() )
00090     str = ";"; // keep something, for isDistributionList to work
00091   insertCustom( "KADDRESSBOOK", s_customFieldName, str ); // replace old value
00092 }
00093 
00094 bool KPIM::DistributionList::isDistributionList( const KABC::Addressee& addr )
00095 {
00096   const TQString str = addr.custom( "KADDRESSBOOK", s_customFieldName );
00097   return !str.isEmpty();
00098 }
00099 
00100 // ###### KDE4: add findByFormattedName to KABC::AddressBook
00101 static KABC::Addressee::List findByFormattedName( KABC::AddressBook* book,
00102                                             const TQString& name,
00103                                             bool caseSensitive = true )
00104 {
00105   KABC::Addressee::List res;
00106   KABC::AddressBook::Iterator abIt;
00107   for ( abIt = book->begin(); abIt != book->end(); ++abIt )
00108   {
00109     if ( caseSensitive && (*abIt).formattedName() == name )
00110       res.append( *abIt );
00111     if ( !caseSensitive && (*abIt).formattedName().lower() == name.lower() )
00112       res.append( *abIt );
00113   }
00114   return res;
00115 }
00116 
00117 KPIM::DistributionList KPIM::DistributionList::findByName( KABC::AddressBook* book,
00118                                                            const TQString& name,
00119                                                            bool caseSensitive )
00120 {
00121   KABC::AddressBook::Iterator abIt;
00122   for ( abIt = book->begin(); abIt != book->end(); ++abIt )
00123   {
00124     if ( isDistributionList( *abIt ) ) {
00125       if ( caseSensitive && (*abIt).formattedName() == name )
00126         return *abIt;
00127       if ( !caseSensitive && (*abIt).formattedName().lower() == name.lower() )
00128         return *abIt;
00129     }
00130   }
00131   return DistributionList();
00132 }
00133 
00134 static KABC::Addressee findByUidOrName( KABC::AddressBook* book, const TQString& uidOrName, const TQString& email )
00135 {
00136   KABC::Addressee a = book->findByUid( uidOrName );
00137   if ( a.isEmpty() ) {
00138     // UID not found, maybe it is a name instead.
00139     // If we have an email, let's use that for the lookup.
00140     // [This is used by e.g. the Kolab resource]
00141     if ( !email.isEmpty() ) {
00142       KABC::Addressee::List lst = book->findByEmail( email );
00143       KABC::Addressee::List::ConstIterator listit = lst.begin();
00144       for ( ; listit != lst.end(); ++listit )
00145         if ( (*listit).formattedName() == uidOrName ) {
00146           a = *listit;
00147           break;
00148         }
00149       if ( !lst.isEmpty() && a.isEmpty() ) { // found that email, but no match on the fullname
00150         a = lst.first(); // probably the last name changed
00151       }
00152     }
00153     // If we don't have an email, or if we didn't find any match for it, look up by full name
00154     if ( a.isEmpty() ) {
00155       // (But this has to be done here, since when loading we might not have the entries yet)
00156       KABC::Addressee::List lst = findByFormattedName( book, uidOrName );
00157       if ( !lst.isEmpty() )
00158         a = lst.first();
00159     }
00160   }
00161   return a;
00162 }
00163 
00164 KPIM::DistributionList::Entry::List KPIM::DistributionList::entries( KABC::AddressBook* book ) const
00165 {
00166   Entry::List res;
00167   const TQString str = custom( "KADDRESSBOOK", s_customFieldName );
00168   const ParseList parseList = parseCustom( str );
00169   for( ParseList::ConstIterator it = parseList.begin(); it != parseList.end(); ++it ) {
00170     const TQString uid = (*it).first;
00171     const TQString email = (*it).second;
00172     // look up contact
00173     KABC::Addressee a = findByUidOrName( book, uid, email );
00174     if ( a.isEmpty() ) {
00175       // ## The old DistributionListManager had a "missing entries" list...
00176       kdWarning() << "Addressee not found: " << uid << endl;
00177     } else {
00178       res.append( Entry( a, email ) );
00179     }
00180   }
00181   return res;
00182 }
00183 
00184 TQStringList KPIM::DistributionList::emails( KABC::AddressBook* book ) const
00185 {
00186   TQStringList emails;
00187 
00188   const TQString str = custom( "KADDRESSBOOK", s_customFieldName );
00189   ParseList parseList = parseCustom( str );
00190   for( ParseList::ConstIterator it = parseList.begin(); it != parseList.end(); ++it ) {
00191     const TQString thisUid = (*it).first;
00192     const TQString thisEmail = (*it).second;
00193 
00194     // look up contact
00195     KABC::Addressee a = findByUidOrName( book, thisUid, thisEmail );
00196     if ( a.isEmpty() ) {
00197       // ## The old DistributionListManager had a "missing entries" list...
00198       continue;
00199     }
00200 
00201     const TQString email = thisEmail.isEmpty() ? a.fullEmail() :
00202                           a.fullEmail( thisEmail );
00203     if ( !email.isEmpty() ) {
00204       emails.append( email );
00205     }
00206   }
00207 
00208   return emails;
00209 }
00210 
00211 TQValueList<KPIM::DistributionList>
00212  KPIM::DistributionList::allDistributionLists( KABC::AddressBook* book )
00213 {
00214   TQValueList<KPIM::DistributionList> lst;
00215   KABC::AddressBook::Iterator abIt;
00216   for ( abIt = book->begin(); abIt != book->end(); ++abIt )
00217   {
00218     if ( isDistributionList( *abIt ) ) {
00219       lst.append( KPIM::DistributionList( *abIt ) );
00220     }
00221   }
00222   return lst;
00223 }