kabc Library API Documentation

addressee.src.cpp

00001 /*
00002     This file is part of libkabc.
00003     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00004     Copyright (c) 2003 Carsten Pfeiffer <pfeiffer@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., 59 Temple Place - Suite 330,
00019     Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #include <qregexp.h>
00023 
00024 #include <ksharedptr.h>
00025 #include <kdebug.h>
00026 #include <kapplication.h>
00027 #include <klocale.h>
00028 
00029 #include "addresseehelper.h"
00030 #include "field.h"
00031 #include "resource.h"
00032 #include "sortmode.h"
00033 
00034 #include "addressee.h"
00035 
00036 using namespace KABC;
00037 
00038 static bool matchBinaryPattern( int value, int pattern );
00039 
00040 template <class L>
00041 static bool listEquals( const QValueList<L>&, const QValueList<L>& );
00042 static bool emailsEquals( const QStringList&, const QStringList& );
00043 
00044 KABC::SortMode *Addressee::mSortMode = 0;
00045 
00046 struct Addressee::AddresseeData : public KShared
00047 {
00048   QString uid;
00049   --VARIABLES--
00050 
00051   PhoneNumber::List phoneNumbers;
00052   Address::List addresses;
00053   Key::List keys;
00054   QStringList emails;
00055   QStringList categories;
00056   QStringList custom;
00057 
00058   Resource *resource;
00059 
00060   bool empty    :1;
00061   bool changed  :1;
00062 };
00063 
00064 Addressee::AddresseeData* Addressee::shared_null = 0;
00065 
00066 Addressee::AddresseeData* Addressee::makeSharedNull()
00067 {
00068   Addressee::shared_null = new AddresseeData;
00069   shared_null->_KShared_ref(); //just in case (we should add KSD)
00070   shared_null->empty = true;
00071   shared_null->changed = false;
00072   shared_null->resource = 0;
00073   return shared_null;
00074 }
00075 
00076 Addressee::Addressee()
00077 {
00078   mData = shared_null ? shared_null : makeSharedNull();
00079 }
00080 
00081 Addressee::~Addressee()
00082 {
00083 }
00084 
00085 Addressee::Addressee( const Addressee &a )
00086 {
00087   mData = a.mData;
00088 }
00089 
00090 Addressee &Addressee::operator=( const Addressee &a )
00091 {
00092   mData = a.mData;
00093   return (*this);
00094 }
00095 
00096 void Addressee::detach()
00097 {
00098   if ( mData.data() == shared_null ) {
00099     mData = new AddresseeData;
00100     mData->empty = true;
00101     mData->changed = false;
00102     mData->resource = 0;
00103     mData->uid = KApplication::randomString( 10 );
00104     return;
00105   } else if ( mData.count() == 1 ) return;
00106 
00107   AddresseeData data = *mData;
00108   mData = new AddresseeData( data );
00109 }
00110 
00111 bool Addressee::operator==( const Addressee &a ) const
00112 {
00113   if ( uid() != a.uid() ) {
00114     kdDebug(5700) << "uid differs" << endl;
00115     return false;
00116   }
00117   --EQUALSTEST--
00118   if ( ( mData->url.isValid() || a.mData->url.isValid() ) &&
00119        ( mData->url != a.mData->url ) ) {
00120     kdDebug(5700) << "url differs" << endl;
00121     return false;
00122   }
00123   if ( !listEquals( mData->phoneNumbers, a.mData->phoneNumbers ) ) {
00124     kdDebug(5700) << "phoneNumbers differs" << endl;
00125     return false;
00126   }
00127   if ( !listEquals( mData->addresses, a.mData->addresses ) ) {
00128     kdDebug(5700) << "addresses differs" << endl;
00129     return false;
00130   }
00131   if ( !listEquals( mData->keys, a.mData->keys ) ) {
00132     kdDebug(5700) << "keys differs" << endl;
00133     return false;
00134   }
00135   if ( !emailsEquals( mData->emails, a.mData->emails ) ) {
00136     kdDebug(5700) << "emails differs" << endl;
00137     return false;
00138   }
00139   if ( !listEquals( mData->categories, a.mData->categories ) ) {
00140     kdDebug(5700) << "categories differs" << endl;
00141     return false;
00142   }
00143   if ( !listEquals( mData->custom, a.mData->custom ) ) {
00144     kdDebug(5700) << "custom differs" << endl;
00145     return false;
00146   }
00147 
00148   return true;
00149 }
00150 
00151 bool Addressee::operator!=( const Addressee &a ) const
00152 {
00153   return !( a == *this );
00154 }
00155 
00156 bool Addressee::isEmpty() const
00157 {
00158   return mData->empty;
00159 }
00160 
00161 void Addressee::setUid( const QString &id )
00162 {
00163   if ( id == mData->uid ) return;
00164   detach();
00165   mData->empty = false;
00166   mData->uid = id;
00167 }
00168 
00169 QString Addressee::uid() const
00170 {
00171   return mData->uid;
00172 }
00173 
00174 QString Addressee::uidLabel()
00175 {
00176   return i18n("Unique Identifier");
00177 }
00178 
00179 --DEFINITIONS--
00180 
00181 void Addressee::setNameFromString( const QString &str )
00182 {
00183   setFormattedName( str );
00184   setName( str );
00185 
00186   // clear all name parts
00187   setPrefix( QString::null );
00188   setGivenName( QString::null );
00189   setAdditionalName( QString::null );
00190   setFamilyName( QString::null );
00191   setSuffix( QString::null );
00192 
00193   if ( str.isEmpty() )
00194     return;
00195 
00196   QString spaceStr = " ";
00197   QString emptyStr = "";
00198   AddresseeHelper *helper = AddresseeHelper::self();
00199       
00200   int i = str.find( ',' );
00201   if( i < 0 ) {
00202     QStringList parts = QStringList::split( spaceStr, str );
00203     int leftOffset = 0;
00204     int rightOffset = parts.count() - 1;
00205 
00206     QString suffix;
00207     while ( rightOffset >= 0 ) {
00208       if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
00209         suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr));
00210         rightOffset--;
00211       } else
00212         break;
00213     }
00214     setSuffix( suffix );
00215 
00216     if ( rightOffset < 0 )
00217       return;
00218 
00219     if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].lower() ) ) {
00220       setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
00221       rightOffset--;
00222     } else {
00223       if ( helper->tradeAsFamilyName() )
00224         setFamilyName( parts[ rightOffset ] );
00225       else
00226         setGivenName( parts[ rightOffset ] );
00227     }
00228 
00229     QString prefix;
00230     while ( leftOffset < rightOffset ) {
00231       if ( helper->containsTitle( parts[ leftOffset ] ) ) {
00232         prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00233         leftOffset++;
00234       } else
00235         break;
00236     }
00237     setPrefix( prefix );
00238 
00239     if ( leftOffset < rightOffset ) {
00240       setGivenName( parts[ leftOffset ] );
00241       leftOffset++;
00242     }
00243 
00244     QString additionalName;
00245     while ( leftOffset < rightOffset ) {
00246       additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00247       leftOffset++;
00248     }
00249     setAdditionalName( additionalName );
00250   } else {
00251     QString part1 = str.left( i );
00252     QString part2 = str.mid( i + 1 );
00253 
00254     QStringList parts = QStringList::split( spaceStr, part1 );
00255     int leftOffset = 0;
00256     int rightOffset = parts.count() - 1;
00257 
00258     if ( parts.count() > 0 ) {
00259 
00260       QString suffix;
00261       while ( rightOffset >= 0 ) {
00262         if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
00263           suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr));
00264           rightOffset--;
00265         } else
00266           break;
00267       }
00268       setSuffix( suffix );
00269 
00270       if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].lower() ) ) {
00271         setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
00272         rightOffset--;
00273       } else
00274         setFamilyName( parts[ rightOffset ] );
00275 
00276       QString prefix;
00277       while ( leftOffset < rightOffset ) {
00278         if ( helper->containsTitle( parts[ leftOffset ] ) ) {
00279           prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00280           leftOffset++;
00281         } else
00282           break;
00283       }
00284     } else {
00285       setPrefix( "" );
00286       setFamilyName( "" );
00287       setSuffix( "" );
00288     }
00289 
00290     parts = QStringList::split( spaceStr, part2 );
00291 
00292     leftOffset = 0;
00293     rightOffset = parts.count();
00294 
00295     if ( parts.count() > 0 ) {
00296 
00297       QString prefix;
00298       while ( leftOffset < rightOffset ) {
00299         if ( helper->containsTitle( parts[ leftOffset ] ) ) {
00300           prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00301           leftOffset++;
00302         } else
00303           break;
00304       }
00305       setPrefix( prefix );
00306 
00307       if ( leftOffset < rightOffset ) {
00308         setGivenName( parts[ leftOffset ] );
00309         leftOffset++;
00310       }
00311 
00312       QString additionalName;
00313       while ( leftOffset < rightOffset ) {
00314         additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00315         leftOffset++;
00316       }
00317       setAdditionalName( additionalName );
00318     } else {
00319       setGivenName( "" );
00320       setAdditionalName( "" );
00321     }
00322   }
00323 }
00324 
00325 QString Addressee::realName() const
00326 {
00327   QString n( formattedName() );
00328   if ( !n.isEmpty() )
00329     return n;
00330 
00331   n = assembledName();
00332   if ( !n.isEmpty() )
00333     return n;
00334 
00335   n = name();
00336   if ( !n.isEmpty() )
00337     return n;
00338 
00339   return organization();
00340 }
00341 
00342 QString Addressee::assembledName() const
00343 {
00344   QString name = prefix() + " " + givenName() + " " + additionalName() + " " +
00345               familyName() + " " + suffix();
00346 
00347   return name.simplifyWhiteSpace();
00348 }
00349 
00350 QString Addressee::fullEmail( const QString &email ) const
00351 {
00352   QString e;
00353   if ( email.isNull() ) {
00354     e = preferredEmail();
00355   } else {
00356     e = email;
00357   }
00358   if ( e.isEmpty() ) return QString::null;
00359 
00360   QString text;
00361   if ( realName().isEmpty() )
00362     text = e;
00363   else {
00364     QRegExp needQuotes( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" );
00365     if ( realName().find( needQuotes ) != -1 )
00366       text = "\"" + realName() + "\" <" + e + ">";
00367     else
00368       text = realName() + " <" + e + ">";
00369   }
00370 
00371   return text;
00372 }
00373 
00374 void Addressee::insertEmail( const QString &email, bool preferred )
00375 {
00376   if ( email.simplifyWhiteSpace().isEmpty() )
00377     return;
00378 
00379   detach();
00380 
00381   QStringList::Iterator it = mData->emails.find( email );
00382 
00383   if ( it != mData->emails.end() ) {
00384     if ( !preferred || it == mData->emails.begin() ) return;
00385     mData->emails.remove( it );
00386     mData->emails.prepend( email );
00387   } else {
00388     if ( preferred ) {
00389       mData->emails.prepend( email );
00390     } else {
00391       mData->emails.append( email );
00392     }
00393   }
00394 }
00395 
00396 void Addressee::removeEmail( const QString &email )
00397 {
00398   detach();
00399 
00400   QStringList::Iterator it = mData->emails.find( email );
00401   if ( it == mData->emails.end() ) return;
00402 
00403   mData->emails.remove( it );
00404 }
00405 
00406 QString Addressee::preferredEmail() const
00407 {
00408   if ( mData->emails.count() == 0 ) return QString::null;
00409   else return mData->emails.first();
00410 }
00411 
00412 QStringList Addressee::emails() const
00413 {
00414   return mData->emails;
00415 }
00416 void Addressee::setEmails( const QStringList& emails ) {
00417   detach();
00418 
00419   mData->emails = emails;
00420 }
00421 void Addressee::insertPhoneNumber( const PhoneNumber &phoneNumber )
00422 {
00423   detach();
00424   mData->empty = false;
00425 
00426   PhoneNumber::List::Iterator it;
00427   for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) {
00428     if ( (*it).id() == phoneNumber.id() ) {
00429       *it = phoneNumber;
00430       return;
00431     }
00432   }
00433   if ( !phoneNumber.number().simplifyWhiteSpace().isEmpty() )
00434     mData->phoneNumbers.append( phoneNumber );
00435 }
00436 
00437 void Addressee::removePhoneNumber( const PhoneNumber &phoneNumber )
00438 {
00439   detach();
00440 
00441   PhoneNumber::List::Iterator it;
00442   for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) {
00443     if ( (*it).id() == phoneNumber.id() ) {
00444       mData->phoneNumbers.remove( it );
00445       return;
00446     }
00447   }
00448 }
00449 
00450 PhoneNumber Addressee::phoneNumber( int type ) const
00451 {
00452   PhoneNumber phoneNumber( "", type );
00453   PhoneNumber::List::ConstIterator it;
00454   for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) {
00455     if ( matchBinaryPattern( (*it).type(), type ) ) {
00456       if ( (*it).type() & PhoneNumber::Pref )
00457         return (*it);
00458       else if ( phoneNumber.number().isEmpty() )
00459         phoneNumber = (*it);
00460     }
00461   }
00462 
00463   return phoneNumber;
00464 }
00465 
00466 PhoneNumber::List Addressee::phoneNumbers() const
00467 {
00468   return mData->phoneNumbers;
00469 }
00470 
00471 PhoneNumber::List Addressee::phoneNumbers( int type ) const
00472 {
00473   PhoneNumber::List list;
00474 
00475   PhoneNumber::List::ConstIterator it;
00476   for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) {
00477     if ( matchBinaryPattern( (*it).type(), type ) ) {
00478       list.append( *it );
00479     }
00480   }
00481   return list;
00482 }
00483 
00484 PhoneNumber Addressee::findPhoneNumber( const QString &id ) const
00485 {
00486   PhoneNumber::List::ConstIterator it;
00487   for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) {
00488     if ( (*it).id() == id ) {
00489       return *it;
00490     }
00491   }
00492   return PhoneNumber();
00493 }
00494 
00495 void Addressee::insertKey( const Key &key )
00496 {
00497   detach();
00498   mData->empty = false;
00499 
00500   Key::List::Iterator it;
00501   for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) {
00502     if ( (*it).id() == key.id() ) {
00503       *it = key;
00504       return;
00505     }
00506   }
00507   mData->keys.append( key );
00508 }
00509 
00510 void Addressee::removeKey( const Key &key )
00511 {
00512   detach();
00513 
00514   Key::List::Iterator it;
00515   for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) {
00516     if ( (*it).id() == key.id() ) {
00517       mData->keys.remove( key );
00518       return;
00519     }
00520   }
00521 }
00522 
00523 Key Addressee::key( int type, QString customTypeString ) const
00524 {
00525   Key::List::ConstIterator it;
00526   for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) {
00527     if ( (*it).type() == type ) {
00528       if ( type == Key::Custom ) {
00529         if ( customTypeString.isEmpty() ) {
00530           return *it;
00531         } else {
00532           if ( (*it).customTypeString() == customTypeString )
00533             return (*it);
00534         }
00535       } else {
00536         return *it;
00537       }
00538     }
00539   }
00540   return Key( QString(), type );
00541 }
00542 
00543 void Addressee::setKeys( const Key::List& list )
00544 {
00545   detach();
00546   mData->keys = list;
00547 }
00548 
00549 Key::List Addressee::keys() const
00550 {
00551   return mData->keys;
00552 }
00553 
00554 Key::List Addressee::keys( int type, QString customTypeString ) const
00555 {
00556   Key::List list;
00557 
00558   Key::List::ConstIterator it;
00559   for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) {
00560     if ( (*it).type() == type ) {
00561       if ( type == Key::Custom ) {
00562         if ( customTypeString.isEmpty() ) {
00563           list.append( *it );
00564         } else {
00565           if ( (*it).customTypeString() == customTypeString )
00566             list.append( *it );
00567         }
00568       } else {
00569         list.append( *it );
00570       }
00571     }
00572   }
00573   return list;
00574 }
00575 
00576 Key Addressee::findKey( const QString &id ) const
00577 {
00578   Key::List::ConstIterator it;
00579   for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) {
00580     if ( (*it).id() == id ) {
00581       return *it;
00582     }
00583   }
00584   return Key();
00585 }
00586 
00587 QString Addressee::asString() const
00588 {
00589   return "Smith, agent Smith...";
00590 }
00591 
00592 void Addressee::dump() const
00593 {
00594   kdDebug(5700) << "Addressee {" << endl;
00595 
00596   kdDebug(5700) << "  Uid: '" << uid() << "'" << endl;
00597 
00598   --DEBUG--
00599 
00600   kdDebug(5700) << "  Emails {" << endl;
00601   const QStringList e = emails();
00602   QStringList::ConstIterator it;
00603   for( it = e.begin(); it != e.end(); ++it ) {
00604     kdDebug(5700) << "    " << (*it) << endl;
00605   }
00606   kdDebug(5700) << "  }" << endl;
00607 
00608   kdDebug(5700) << "  PhoneNumbers {" << endl;
00609   const PhoneNumber::List p = phoneNumbers();
00610   PhoneNumber::List::ConstIterator it2;
00611   for( it2 = p.begin(); it2 != p.end(); ++it2 ) {
00612     kdDebug(5700) << "    Type: " << int((*it2).type()) << " Number: " << (*it2).number() << endl;
00613   }
00614   kdDebug(5700) << "  }" << endl;
00615 
00616   const Address::List a = addresses();
00617   Address::List::ConstIterator it3;
00618   for( it3 = a.begin(); it3 != a.end(); ++it3 ) {
00619     (*it3).dump();
00620   }
00621 
00622   kdDebug(5700) << "  Keys {" << endl;
00623   const Key::List k = keys();
00624   Key::List::ConstIterator it4;
00625   for( it4 = k.begin(); it4 != k.end(); ++it4 ) {
00626     kdDebug(5700) << "    Type: " << int((*it4).type()) <<
00627                      " Key: " << (*it4).textData() <<
00628                      " CustomString: " << (*it4).customTypeString() << endl;
00629   }
00630   kdDebug(5700) << "  }" << endl;
00631 
00632   kdDebug(5700) << "}" << endl;
00633 }
00634 
00635 
00636 void Addressee::insertAddress( const Address &address )
00637 {
00638   if ( address.isEmpty() )
00639     return;
00640 
00641   detach();
00642   mData->empty = false;
00643 
00644   Address::List::Iterator it;
00645   for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) {
00646     if ( (*it).id() == address.id() ) {
00647       *it = address;
00648       return;
00649     }
00650   }
00651 
00652   mData->addresses.append( address );
00653 }
00654 
00655 void Addressee::removeAddress( const Address &address )
00656 {
00657   detach();
00658 
00659   Address::List::Iterator it;
00660   for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) {
00661     if ( (*it).id() == address.id() ) {
00662       mData->addresses.remove( it );
00663       return;
00664     }
00665   }
00666 }
00667 
00668 Address Addressee::address( int type ) const
00669 {
00670   Address address( type );
00671   Address::List::ConstIterator it;
00672   for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) {
00673     if ( matchBinaryPattern( (*it).type(), type ) ) {
00674       if ( (*it).type() & Address::Pref )
00675         return (*it);
00676       else if ( address.isEmpty() )
00677         address = (*it);
00678     }
00679   }
00680 
00681   return address;
00682 }
00683 
00684 Address::List Addressee::addresses() const
00685 {
00686   return mData->addresses;
00687 }
00688 
00689 Address::List Addressee::addresses( int type ) const
00690 {
00691   Address::List list;
00692 
00693   Address::List::ConstIterator it;
00694   for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) {
00695     if ( matchBinaryPattern( (*it).type(), type ) ) {
00696       list.append( *it );
00697     }
00698   }
00699 
00700   return list;
00701 }
00702 
00703 Address Addressee::findAddress( const QString &id ) const
00704 {
00705   Address::List::ConstIterator it;
00706   for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) {
00707     if ( (*it).id() == id ) {
00708       return *it;
00709     }
00710   }
00711   return Address();
00712 }
00713 
00714 void Addressee::insertCategory( const QString &c )
00715 {
00716   detach();
00717   mData->empty = false;
00718 
00719   if ( mData->categories.findIndex( c ) != -1 ) return;
00720 
00721   mData->categories.append( c );
00722 }
00723 
00724 void Addressee::removeCategory( const QString &c )
00725 {
00726   detach();
00727 
00728   QStringList::Iterator it = mData->categories.find( c );
00729   if ( it == mData->categories.end() ) return;
00730 
00731   mData->categories.remove( it );
00732 }
00733 
00734 bool Addressee::hasCategory( const QString &c ) const
00735 {
00736   return ( mData->categories.findIndex( c ) != -1 );
00737 }
00738 
00739 void Addressee::setCategories( const QStringList &c )
00740 {
00741   detach();
00742   mData->empty = false;
00743 
00744   mData->categories = c;
00745 }
00746 
00747 QStringList Addressee::categories() const
00748 {
00749   return mData->categories;
00750 }
00751 
00752 void Addressee::insertCustom( const QString &app, const QString &name,
00753                               const QString &value )
00754 {
00755   if ( value.isEmpty() || name.isEmpty() || app.isEmpty() ) return;
00756 
00757   detach();
00758   mData->empty = false;
00759 
00760   QString qualifiedName = app + "-" + name + ":";
00761 
00762   QStringList::Iterator it;
00763   for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) {
00764     if ( (*it).startsWith( qualifiedName ) ) {
00765       (*it) = qualifiedName + value;
00766       return;
00767     }
00768   }
00769 
00770   mData->custom.append( qualifiedName + value );
00771 }
00772 
00773 void Addressee::removeCustom( const QString &app, const QString &name)
00774 {
00775   detach();
00776 
00777   QString qualifiedName = app + "-" + name + ":";
00778 
00779   QStringList::Iterator it;
00780   for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) {
00781     if ( (*it).startsWith( qualifiedName ) ) {
00782       mData->custom.remove( it );
00783       return;
00784     }
00785   }
00786 }
00787 
00788 QString Addressee::custom( const QString &app, const QString &name ) const
00789 {
00790   QString qualifiedName = app + "-" + name + ":";
00791   QString value;
00792 
00793   QStringList::ConstIterator it;
00794   for( it = mData->custom.constBegin(); it != mData->custom.constEnd(); ++it ) {
00795     if ( (*it).startsWith( qualifiedName ) ) {
00796       value = (*it).mid( (*it).find( ":" ) + 1 );
00797       break;
00798     }
00799   }
00800 
00801   return value;
00802 }
00803 
00804 void Addressee::setCustoms( const QStringList &l )
00805 {
00806   detach();
00807   mData->empty = false;
00808 
00809   mData->custom = l;
00810 }
00811 
00812 QStringList Addressee::customs() const
00813 {
00814   return mData->custom;
00815 }
00816 
00817 void Addressee::parseEmailAddress( const QString &rawEmail, QString &fullName,
00818                                    QString &email)
00819 {
00820   int startPos, endPos, len;
00821   QString partA, partB, result;
00822   char endCh = '>';
00823 
00824   startPos = rawEmail.find( '<' );
00825   if ( startPos < 0 ) {
00826     startPos = rawEmail.find( '(' );
00827     endCh = ')';
00828   }
00829 
00830   if ( startPos < 0 ) {
00831     // We couldn't find any separators, so we assume the whole string
00832     // is the email address
00833     email = rawEmail;
00834     fullName = "";
00835   } else {
00836     // We have a start position, try to find an end
00837     endPos = rawEmail.find( endCh, startPos + 1 );
00838 
00839     if ( endPos < 0 ) {
00840       // We couldn't find the end of the email address. We can only
00841       // assume the entire string is the email address.
00842       email = rawEmail;
00843       fullName = "";
00844     } else {
00845       // We have a start and end to the email address
00846 
00847       // Grab the name part
00848       QString left = rawEmail.left( startPos ).stripWhiteSpace();
00849       // grab the email part
00850       QString right = rawEmail.mid( startPos + 1, endPos - startPos - 1 )
00851                               .stripWhiteSpace();
00852 
00853       // Either "Name <email>" or "email (Name)"
00854       if ( endCh == '>' ) {
00855         fullName = left;
00856         email = right;
00857       } else { // endCh == ')'
00858         fullName = right;
00859         email = left;
00860       }
00861 
00862       // Check that we do not have any extra characters on the end of the
00863       // strings
00864       len = fullName.length();
00865       if ( fullName[ 0 ] == '"' && fullName[ len - 1 ] == '"' )
00866         fullName = fullName.mid( 1, len - 2 );
00867       else if ( fullName[ 0 ] == '(' && fullName[ len - 1 ] == ')' )
00868         fullName = fullName.mid( 1, len - 2 );
00869 
00870       len = email.length();
00871       if ( email[ 0 ] == '<' && email[ len - 1 ] == '>' )
00872         email = email.mid( 1, len - 2 );
00873     }
00874   }
00875 }
00876 
00877 void Addressee::setResource( Resource *resource )
00878 {
00879   detach();
00880   mData->resource = resource;
00881 }
00882 
00883 Resource *Addressee::resource() const
00884 {
00885   return mData->resource;
00886 }
00887 
00888 void Addressee::setChanged( bool value )
00889 {
00890   detach();
00891   mData->changed = value;
00892 }
00893 
00894 bool Addressee::changed() const
00895 {
00896   return mData->changed;
00897 }
00898 
00899 void Addressee::setSortMode( KABC::SortMode *mode )
00900 {
00901   mSortMode = mode;
00902 }
00903 
00904 bool Addressee::operator< ( const Addressee &addr )
00905 {
00906   if ( !mSortMode )
00907     return false;
00908   else
00909     return mSortMode->lesser( *this, addr );
00910 }
00911 
00912 QDataStream &KABC::operator<<( QDataStream &s, const Addressee &a )
00913 {
00914   if (!a.mData) return s;
00915 
00916   s << a.uid();
00917 
00918   --STREAMOUT--
00919   s << a.mData->phoneNumbers;
00920   s << a.mData->addresses;
00921   s << a.mData->emails;
00922   s << a.mData->categories;
00923   s << a.mData->custom;
00924   s << a.mData->keys;
00925   return s;
00926 }
00927 
00928 QDataStream &KABC::operator>>( QDataStream &s, Addressee &a )
00929 {
00930   if (!a.mData) return s;
00931 
00932   s >> a.mData->uid;
00933 
00934   --STREAMIN--
00935   s >> a.mData->phoneNumbers;
00936   s >> a.mData->addresses;
00937   s >> a.mData->emails;
00938   s >> a.mData->categories;
00939   s >> a.mData->custom;
00940   s >> a.mData->keys;
00941 
00942   a.mData->empty = false;
00943 
00944   return s;
00945 }
00946 
00947 bool matchBinaryPattern( int value, int pattern )
00948 {
00955   if ( pattern == 0 )
00956     return ( value == 0 );
00957   else
00958     return ( pattern == ( pattern & value ) );
00959 }
00960 
00961 template <class L>
00962 bool listEquals( const QValueList<L> &list, const QValueList<L> &pattern )
00963 {
00964   if ( list.count() != pattern.count() )
00965     return false;
00966 
00967   for ( uint i = 0; i < list.count(); ++i )
00968     if ( pattern.find( list[ i ] ) == pattern.end() )
00969       return false;
00970 
00971   return true;
00972 }
00973 
00974 bool emailsEquals( const QStringList &list, const QStringList &pattern )
00975 {
00976   if ( list.count() != pattern.count() )
00977     return false;
00978 
00979   if ( list.first() != pattern.first() )
00980     return false;
00981 
00982   QStringList::ConstIterator it;
00983   for ( it = list.begin(); it != list.end(); ++it )
00984     if ( pattern.find( *it ) == pattern.end() )
00985       return false;
00986 
00987   return true;
00988 }
KDE Logo
This file is part of the documentation for kabc Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Apr 22 16:06:54 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003