kabc Library: addressee.src.cpp Source File (kabc Library)

| # kabc Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

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

This file is part of the documentation for kabc Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:31:29 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003