• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kabc
 

kabc

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

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kabc

Skip menu "kabc"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kabc by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |