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