00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qregexp.h>
00025
00026 #include <ksharedptr.h>
00027 #include <kdebug.h>
00028 #include <kapplication.h>
00029 #include <klocale.h>
00030
00031 #include "addresseehelper.h"
00032 #include "field.h"
00033 #include "resource.h"
00034 #include "sortmode.h"
00035
00036 #include "addressee.h"
00037
00038 using namespace KABC;
00039
00040 static bool matchBinaryPattern( int value, int pattern );
00041
00042 template <class L>
00043 static bool listEquals( const QValueList<L>&, const QValueList<L>& );
00044 static bool emailsEquals( const QStringList&, const QStringList& );
00045
00046 KABC::SortMode *Addressee::mSortMode = 0;
00047
00048 struct Addressee::AddresseeData : public KShared
00049 {
00050 QString uid;
00051 QString name;
00052 QString formattedName;
00053 QString familyName;
00054 QString givenName;
00055 QString additionalName;
00056 QString prefix;
00057 QString suffix;
00058 QString nickName;
00059 QDateTime birthday;
00060 QString mailer;
00061 TimeZone timeZone;
00062 Geo geo;
00063 QString title;
00064 QString role;
00065 QString organization;
00066 QString note;
00067 QString productId;
00068 QDateTime revision;
00069 QString sortString;
00070 KURL url;
00071 Secrecy secrecy;
00072 Picture logo;
00073 Picture photo;
00074 Sound sound;
00075 Agent agent;
00076
00077 PhoneNumber::List phoneNumbers;
00078 Address::List addresses;
00079 Key::List keys;
00080 QStringList emails;
00081 QStringList categories;
00082 QStringList custom;
00083
00084 Resource *resource;
00085
00086 bool empty :1;
00087 bool changed :1;
00088 };
00089
00090 Addressee::AddresseeData* Addressee::shared_null = 0;
00091
00092 Addressee::AddresseeData* Addressee::makeSharedNull()
00093 {
00094 Addressee::shared_null = new AddresseeData;
00095 shared_null->_KShared_ref();
00096 shared_null->empty = true;
00097 shared_null->changed = false;
00098 shared_null->resource = 0;
00099 return shared_null;
00100 }
00101
00102 Addressee::Addressee()
00103 {
00104 mData = shared_null ? shared_null : makeSharedNull();
00105 }
00106
00107 Addressee::~Addressee()
00108 {
00109 }
00110
00111 Addressee::Addressee( const Addressee &a )
00112 {
00113 mData = a.mData;
00114 }
00115
00116 Addressee &Addressee::operator=( const Addressee &a )
00117 {
00118 if ( this == &a )
00119 return (*this);
00120
00121 mData = a.mData;
00122 return (*this);
00123 }
00124
00125 void Addressee::detach()
00126 {
00127 if ( mData.data() == shared_null ) {
00128 mData = new AddresseeData;
00129 mData->empty = true;
00130 mData->changed = false;
00131 mData->resource = 0;
00132 mData->uid = KApplication::randomString( 10 );
00133 return;
00134 } else if ( mData.count() == 1 ) return;
00135
00136 AddresseeData data = *mData;
00137 mData = new AddresseeData( data );
00138 }
00139
00140 bool Addressee::operator==( const Addressee &a ) const
00141 {
00142 if ( uid() != a.uid() ) {
00143 kdDebug(5700) << "uid differs" << endl;
00144 return false;
00145 }
00146 if ( mData->name != a.mData->name &&
00147 !( mData->name.isEmpty() && a.mData->name.isEmpty() ) ) {
00148 kdDebug(5700) << "name differs" << endl;
00149 return false;
00150 }
00151 if ( mData->formattedName != a.mData->formattedName &&
00152 !( mData->formattedName.isEmpty() && a.mData->formattedName.isEmpty() ) ) {
00153 kdDebug(5700) << "formattedName differs" << endl;
00154 return false;
00155 }
00156 if ( mData->familyName != a.mData->familyName &&
00157 !( mData->familyName.isEmpty() && a.mData->familyName.isEmpty() ) ) {
00158 kdDebug(5700) << "familyName differs" << endl;
00159 return false;
00160 }
00161 if ( mData->givenName != a.mData->givenName &&
00162 !( mData->givenName.isEmpty() && a.mData->givenName.isEmpty() ) ) {
00163 kdDebug(5700) << "givenName differs" << endl;
00164 return false;
00165 }
00166 if ( mData->additionalName != a.mData->additionalName &&
00167 !( mData->additionalName.isEmpty() && a.mData->additionalName.isEmpty() ) ) {
00168 kdDebug(5700) << "additionalName differs" << endl;
00169 return false;
00170 }
00171 if ( mData->prefix != a.mData->prefix &&
00172 !( mData->prefix.isEmpty() && a.mData->prefix.isEmpty() ) ) {
00173 kdDebug(5700) << "prefix differs" << endl;
00174 return false;
00175 }
00176 if ( mData->suffix != a.mData->suffix &&
00177 !( mData->suffix.isEmpty() && a.mData->suffix.isEmpty() ) ) {
00178 kdDebug(5700) << "suffix differs" << endl;
00179 return false;
00180 }
00181 if ( mData->nickName != a.mData->nickName &&
00182 !( mData->nickName.isEmpty() && a.mData->nickName.isEmpty() ) ) {
00183 kdDebug(5700) << "nickName differs" << endl;
00184 return false;
00185 }
00186 if ( mData->birthday != a.mData->birthday ) {
00187 kdDebug(5700) << "birthday differs" << endl;
00188 return false;
00189 }
00190 if ( mData->mailer != a.mData->mailer &&
00191 !( mData->mailer.isEmpty() && a.mData->mailer.isEmpty() ) ) {
00192 kdDebug(5700) << "mailer differs" << endl;
00193 return false;
00194 }
00195 if ( mData->timeZone != a.mData->timeZone ) {
00196 kdDebug(5700) << "timeZone differs" << endl;
00197 return false;
00198 }
00199 if ( mData->geo != a.mData->geo ) {
00200 kdDebug(5700) << "geo differs" << endl;
00201 return false;
00202 }
00203 if ( mData->title != a.mData->title &&
00204 !( mData->title.isEmpty() && a.mData->title.isEmpty() ) ) {
00205 kdDebug(5700) << "title differs" << endl;
00206 return false;
00207 }
00208 if ( mData->role != a.mData->role &&
00209 !( mData->role.isEmpty() && a.mData->role.isEmpty() ) ) {
00210 kdDebug(5700) << "role differs" << endl;
00211 return false;
00212 }
00213 if ( mData->organization != a.mData->organization &&
00214 !( mData->organization.isEmpty() && a.mData->organization.isEmpty() ) ) {
00215 kdDebug(5700) << "organization differs" << endl;
00216 return false;
00217 }
00218 if ( mData->note != a.mData->note &&
00219 !( mData->note.isEmpty() && a.mData->note.isEmpty() ) ) {
00220 kdDebug(5700) << "note differs" << endl;
00221 return false;
00222 }
00223 if ( mData->productId != a.mData->productId &&
00224 !( mData->productId.isEmpty() && a.mData->productId.isEmpty() ) ) {
00225 kdDebug(5700) << "productId differs" << endl;
00226 return false;
00227 }
00228 if ( mData->sortString != a.mData->sortString &&
00229 !( mData->sortString.isEmpty() && a.mData->sortString.isEmpty() ) ) {
00230 kdDebug(5700) << "sortString differs" << endl;
00231 return false;
00232 }
00233 if ( mData->secrecy != a.mData->secrecy ) {
00234 kdDebug(5700) << "secrecy differs" << endl;
00235 return false;
00236 }
00237 if ( mData->logo != a.mData->logo ) {
00238 kdDebug(5700) << "logo differs" << endl;
00239 return false;
00240 }
00241 if ( mData->photo != a.mData->photo ) {
00242 kdDebug(5700) << "photo differs" << endl;
00243 return false;
00244 }
00245 if ( mData->sound != a.mData->sound ) {
00246 kdDebug(5700) << "sound differs" << endl;
00247 return false;
00248 }
00249 if ( mData->agent != a.mData->agent ) {
00250 kdDebug(5700) << "agent differs" << endl;
00251 return false;
00252 }
00253 if ( ( mData->url.isValid() || a.mData->url.isValid() ) &&
00254 ( mData->url != a.mData->url ) ) {
00255 kdDebug(5700) << "url differs" << endl;
00256 return false;
00257 }
00258 if ( !listEquals( mData->phoneNumbers, a.mData->phoneNumbers ) ) {
00259 kdDebug(5700) << "phoneNumbers differs" << endl;
00260 return false;
00261 }
00262 if ( !listEquals( mData->addresses, a.mData->addresses ) ) {
00263 kdDebug(5700) << "addresses differs" << endl;
00264 return false;
00265 }
00266 if ( !listEquals( mData->keys, a.mData->keys ) ) {
00267 kdDebug(5700) << "keys differs" << endl;
00268 return false;
00269 }
00270 if ( !emailsEquals( mData->emails, a.mData->emails ) ) {
00271 kdDebug(5700) << "emails differs" << endl;
00272 return false;
00273 }
00274 if ( !listEquals( mData->categories, a.mData->categories ) ) {
00275 kdDebug(5700) << "categories differs" << endl;
00276 return false;
00277 }
00278 if ( !listEquals( mData->custom, a.mData->custom ) ) {
00279 kdDebug(5700) << "custom differs" << endl;
00280 return false;
00281 }
00282
00283 return true;
00284 }
00285
00286 bool Addressee::operator!=( const Addressee &a ) const
00287 {
00288 return !( a == *this );
00289 }
00290
00291 bool Addressee::isEmpty() const
00292 {
00293 return mData->empty;
00294 }
00295
00296 void Addressee::setUid( const QString &id )
00297 {
00298 if ( id == mData->uid ) return;
00299 detach();
00300 mData->empty = false;
00301 mData->uid = id;
00302 }
00303
00304 QString Addressee::uid() const
00305 {
00306 return mData->uid;
00307 }
00308
00309 QString Addressee::uidLabel()
00310 {
00311 return i18n("Unique Identifier");
00312 }
00313
00314 void Addressee::setName( const QString &name )
00315 {
00316 if ( name == mData->name ) return;
00317 detach();
00318 mData->empty = false;
00319 mData->name = name;
00320 }
00321
00322 QString Addressee::name() const
00323 {
00324 return mData->name;
00325 }
00326
00327 QString Addressee::nameLabel()
00328 {
00329 return i18n("Name");
00330 }
00331
00332
00333 void Addressee::setFormattedName( const QString &formattedName )
00334 {
00335 if ( formattedName == mData->formattedName ) return;
00336 detach();
00337 mData->empty = false;
00338 mData->formattedName = formattedName;
00339 }
00340
00341 QString Addressee::formattedName() const
00342 {
00343 return mData->formattedName;
00344 }
00345
00346 QString Addressee::formattedNameLabel()
00347 {
00348 return i18n("Formatted Name");
00349 }
00350
00351
00352 void Addressee::setFamilyName( const QString &familyName )
00353 {
00354 if ( familyName == mData->familyName ) return;
00355 detach();
00356 mData->empty = false;
00357 mData->familyName = familyName;
00358 }
00359
00360 QString Addressee::familyName() const
00361 {
00362 return mData->familyName;
00363 }
00364
00365 QString Addressee::familyNameLabel()
00366 {
00367 return i18n("Family Name");
00368 }
00369
00370
00371 void Addressee::setGivenName( const QString &givenName )
00372 {
00373 if ( givenName == mData->givenName ) return;
00374 detach();
00375 mData->empty = false;
00376 mData->givenName = givenName;
00377 }
00378
00379 QString Addressee::givenName() const
00380 {
00381 return mData->givenName;
00382 }
00383
00384 QString Addressee::givenNameLabel()
00385 {
00386 return i18n("Given Name");
00387 }
00388
00389
00390 void Addressee::setAdditionalName( const QString &additionalName )
00391 {
00392 if ( additionalName == mData->additionalName ) return;
00393 detach();
00394 mData->empty = false;
00395 mData->additionalName = additionalName;
00396 }
00397
00398 QString Addressee::additionalName() const
00399 {
00400 return mData->additionalName;
00401 }
00402
00403 QString Addressee::additionalNameLabel()
00404 {
00405 return i18n("Additional Names");
00406 }
00407
00408
00409 void Addressee::setPrefix( const QString &prefix )
00410 {
00411 if ( prefix == mData->prefix ) return;
00412 detach();
00413 mData->empty = false;
00414 mData->prefix = prefix;
00415 }
00416
00417 QString Addressee::prefix() const
00418 {
00419 return mData->prefix;
00420 }
00421
00422 QString Addressee::prefixLabel()
00423 {
00424 return i18n("Honorific Prefixes");
00425 }
00426
00427
00428 void Addressee::setSuffix( const QString &suffix )
00429 {
00430 if ( suffix == mData->suffix ) return;
00431 detach();
00432 mData->empty = false;
00433 mData->suffix = suffix;
00434 }
00435
00436 QString Addressee::suffix() const
00437 {
00438 return mData->suffix;
00439 }
00440
00441 QString Addressee::suffixLabel()
00442 {
00443 return i18n("Honorific Suffixes");
00444 }
00445
00446
00447 void Addressee::setNickName( const QString &nickName )
00448 {
00449 if ( nickName == mData->nickName ) return;
00450 detach();
00451 mData->empty = false;
00452 mData->nickName = nickName;
00453 }
00454
00455 QString Addressee::nickName() const
00456 {
00457 return mData->nickName;
00458 }
00459
00460 QString Addressee::nickNameLabel()
00461 {
00462 return i18n("Nick Name");
00463 }
00464
00465
00466 void Addressee::setBirthday( const QDateTime &birthday )
00467 {
00468 if ( birthday == mData->birthday ) return;
00469 detach();
00470 mData->empty = false;
00471 mData->birthday = birthday;
00472 }
00473
00474 QDateTime Addressee::birthday() const
00475 {
00476 return mData->birthday;
00477 }
00478
00479 QString Addressee::birthdayLabel()
00480 {
00481 return i18n("Birthday");
00482 }
00483
00484
00485 QString Addressee::homeAddressStreetLabel()
00486 {
00487 return i18n("Home Address Street");
00488 }
00489
00490
00491 QString Addressee::homeAddressLocalityLabel()
00492 {
00493 return i18n("Home Address City");
00494 }
00495
00496
00497 QString Addressee::homeAddressRegionLabel()
00498 {
00499 return i18n("Home Address State");
00500 }
00501
00502
00503 QString Addressee::homeAddressPostalCodeLabel()
00504 {
00505 return i18n("Home Address Zip Code");
00506 }
00507
00508
00509 QString Addressee::homeAddressCountryLabel()
00510 {
00511 return i18n("Home Address Country");
00512 }
00513
00514
00515 QString Addressee::homeAddressLabelLabel()
00516 {
00517 return i18n("Home Address Label");
00518 }
00519
00520
00521 QString Addressee::businessAddressStreetLabel()
00522 {
00523 return i18n("Business Address Street");
00524 }
00525
00526
00527 QString Addressee::businessAddressLocalityLabel()
00528 {
00529 return i18n("Business Address City");
00530 }
00531
00532
00533 QString Addressee::businessAddressRegionLabel()
00534 {
00535 return i18n("Business Address State");
00536 }
00537
00538
00539 QString Addressee::businessAddressPostalCodeLabel()
00540 {
00541 return i18n("Business Address Zip Code");
00542 }
00543
00544
00545 QString Addressee::businessAddressCountryLabel()
00546 {
00547 return i18n("Business Address Country");
00548 }
00549
00550
00551 QString Addressee::businessAddressLabelLabel()
00552 {
00553 return i18n("Business Address Label");
00554 }
00555
00556
00557 QString Addressee::homePhoneLabel()
00558 {
00559 return i18n("Home Phone");
00560 }
00561
00562
00563 QString Addressee::businessPhoneLabel()
00564 {
00565 return i18n("Business Phone");
00566 }
00567
00568
00569 QString Addressee::mobilePhoneLabel()
00570 {
00571 return i18n("Mobile Phone");
00572 }
00573
00574
00575 QString Addressee::homeFaxLabel()
00576 {
00577 return i18n("Home Fax");
00578 }
00579
00580
00581 QString Addressee::businessFaxLabel()
00582 {
00583 return i18n("Business Fax");
00584 }
00585
00586
00587 QString Addressee::carPhoneLabel()
00588 {
00589 return i18n("Car Phone");
00590 }
00591
00592
00593 QString Addressee::isdnLabel()
00594 {
00595 return i18n("ISDN");
00596 }
00597
00598
00599 QString Addressee::pagerLabel()
00600 {
00601 return i18n("Pager");
00602 }
00603
00604
00605 QString Addressee::emailLabel()
00606 {
00607 return i18n("Email Address");
00608 }
00609
00610
00611 void Addressee::setMailer( const QString &mailer )
00612 {
00613 if ( mailer == mData->mailer ) return;
00614 detach();
00615 mData->empty = false;
00616 mData->mailer = mailer;
00617 }
00618
00619 QString Addressee::mailer() const
00620 {
00621 return mData->mailer;
00622 }
00623
00624 QString Addressee::mailerLabel()
00625 {
00626 return i18n("Mail Client");
00627 }
00628
00629
00630 void Addressee::setTimeZone( const TimeZone &timeZone )
00631 {
00632 if ( timeZone == mData->timeZone ) return;
00633 detach();
00634 mData->empty = false;
00635 mData->timeZone = timeZone;
00636 }
00637
00638 TimeZone Addressee::timeZone() const
00639 {
00640 return mData->timeZone;
00641 }
00642
00643 QString Addressee::timeZoneLabel()
00644 {
00645 return i18n("Time Zone");
00646 }
00647
00648
00649 void Addressee::setGeo( const Geo &geo )
00650 {
00651 if ( geo == mData->geo ) return;
00652 detach();
00653 mData->empty = false;
00654 mData->geo = geo;
00655 }
00656
00657 Geo Addressee::geo() const
00658 {
00659 return mData->geo;
00660 }
00661
00662 QString Addressee::geoLabel()
00663 {
00664 return i18n("Geographic Position");
00665 }
00666
00667
00668 void Addressee::setTitle( const QString &title )
00669 {
00670 if ( title == mData->title ) return;
00671 detach();
00672 mData->empty = false;
00673 mData->title = title;
00674 }
00675
00676 QString Addressee::title() const
00677 {
00678 return mData->title;
00679 }
00680
00681 QString Addressee::titleLabel()
00682 {
00683 return i18n("person","Title");
00684 }
00685
00686
00687 void Addressee::setRole( const QString &role )
00688 {
00689 if ( role == mData->role ) return;
00690 detach();
00691 mData->empty = false;
00692 mData->role = role;
00693 }
00694
00695 QString Addressee::role() const
00696 {
00697 return mData->role;
00698 }
00699
00700 QString Addressee::roleLabel()
00701 {
00702 return i18n("person in organization","Role");
00703 }
00704
00705
00706 void Addressee::setOrganization( const QString &organization )
00707 {
00708 if ( organization == mData->organization ) return;
00709 detach();
00710 mData->empty = false;
00711 mData->organization = organization;
00712 }
00713
00714 QString Addressee::organization() const
00715 {
00716 return mData->organization;
00717 }
00718
00719 QString Addressee::organizationLabel()
00720 {
00721 return i18n("Organization");
00722 }
00723
00724
00725 void Addressee::setNote( const QString ¬e )
00726 {
00727 if ( note == mData->note ) return;
00728 detach();
00729 mData->empty = false;
00730 mData->note = note;
00731 }
00732
00733 QString Addressee::note() const
00734 {
00735 return mData->note;
00736 }
00737
00738 QString Addressee::noteLabel()
00739 {
00740 return i18n("Note");
00741 }
00742
00743
00744 void Addressee::setProductId( const QString &productId )
00745 {
00746 if ( productId == mData->productId ) return;
00747 detach();
00748 mData->empty = false;
00749 mData->productId = productId;
00750 }
00751
00752 QString Addressee::productId() const
00753 {
00754 return mData->productId;
00755 }
00756
00757 QString Addressee::productIdLabel()
00758 {
00759 return i18n("Product Identifier");
00760 }
00761
00762
00763 void Addressee::setRevision( const QDateTime &revision )
00764 {
00765 if ( revision == mData->revision ) return;
00766 detach();
00767 mData->empty = false;
00768 mData->revision = revision;
00769 }
00770
00771 QDateTime Addressee::revision() const
00772 {
00773 return mData->revision;
00774 }
00775
00776 QString Addressee::revisionLabel()
00777 {
00778 return i18n("Revision Date");
00779 }
00780
00781
00782 void Addressee::setSortString( const QString &sortString )
00783 {
00784 if ( sortString == mData->sortString ) return;
00785 detach();
00786 mData->empty = false;
00787 mData->sortString = sortString;
00788 }
00789
00790 QString Addressee::sortString() const
00791 {
00792 return mData->sortString;
00793 }
00794
00795 QString Addressee::sortStringLabel()
00796 {
00797 return i18n("Sort String");
00798 }
00799
00800
00801 void Addressee::setUrl( const KURL &url )
00802 {
00803 if ( url == mData->url ) return;
00804 detach();
00805 mData->empty = false;
00806 mData->url = url;
00807 }
00808
00809 KURL Addressee::url() const
00810 {
00811 return mData->url;
00812 }
00813
00814 QString Addressee::urlLabel()
00815 {
00816 return i18n("Homepage");
00817 }
00818
00819
00820 void Addressee::setSecrecy( const Secrecy &secrecy )
00821 {
00822 if ( secrecy == mData->secrecy ) return;
00823 detach();
00824 mData->empty = false;
00825 mData->secrecy = secrecy;
00826 }
00827
00828 Secrecy Addressee::secrecy() const
00829 {
00830 return mData->secrecy;
00831 }
00832
00833 QString Addressee::secrecyLabel()
00834 {
00835 return i18n("Security Class");
00836 }
00837
00838
00839 void Addressee::setLogo( const Picture &logo )
00840 {
00841 if ( logo == mData->logo ) return;
00842 detach();
00843 mData->empty = false;
00844 mData->logo = logo;
00845 }
00846
00847 Picture Addressee::logo() const
00848 {
00849 return mData->logo;
00850 }
00851
00852 QString Addressee::logoLabel()
00853 {
00854 return i18n("Logo");
00855 }
00856
00857
00858 void Addressee::setPhoto( const Picture &photo )
00859 {
00860 if ( photo == mData->photo ) return;
00861 detach();
00862 mData->empty = false;
00863 mData->photo = photo;
00864 }
00865
00866 Picture Addressee::photo() const
00867 {
00868 return mData->photo;
00869 }
00870
00871 QString Addressee::photoLabel()
00872 {
00873 return i18n("Photo");
00874 }
00875
00876
00877 void Addressee::setSound( const Sound &sound )
00878 {
00879 if ( sound == mData->sound ) return;
00880 detach();
00881 mData->empty = false;
00882 mData->sound = sound;
00883 }
00884
00885 Sound Addressee::sound() const
00886 {
00887 return mData->sound;
00888 }
00889
00890 QString Addressee::soundLabel()
00891 {
00892 return i18n("Sound");
00893 }
00894
00895
00896 void Addressee::setAgent( const Agent &agent )
00897 {
00898 if ( agent == mData->agent ) return;
00899 detach();
00900 mData->empty = false;
00901 mData->agent = agent;
00902 }
00903
00904 Agent Addressee::agent() const
00905 {
00906 return mData->agent;
00907 }
00908
00909 QString Addressee::agentLabel()
00910 {
00911 return i18n("Agent");
00912 }
00913
00914
00915
00916 void Addressee::setNameFromString( const QString &s )
00917 {
00918 QString str = s;
00919
00920 if ( str.length() > 1 && s[ 0 ] == '"' && s[ s.length() - 1 ] == '"' )
00921 str = s.mid( 1, s.length() - 2 );
00922
00923 setFormattedName( str );
00924 setName( str );
00925
00926
00927 setPrefix( QString::null );
00928 setGivenName( QString::null );
00929 setAdditionalName( QString::null );
00930 setFamilyName( QString::null );
00931 setSuffix( QString::null );
00932
00933 if ( str.isEmpty() )
00934 return;
00935
00936 QString spaceStr = " ";
00937 QString emptyStr = "";
00938 AddresseeHelper *helper = AddresseeHelper::self();
00939
00940 int i = str.find( ',' );
00941 if( i < 0 ) {
00942 QStringList parts = QStringList::split( spaceStr, str );
00943 int leftOffset = 0;
00944 int rightOffset = parts.count() - 1;
00945
00946 QString suffix;
00947 while ( rightOffset >= 0 ) {
00948 if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
00949 suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr));
00950 rightOffset--;
00951 } else
00952 break;
00953 }
00954 setSuffix( suffix );
00955
00956 if ( rightOffset < 0 )
00957 return;
00958
00959 QStringList inclusionList;
00960 for ( int n = 1; (rightOffset - n >= 0) && (n < 4); ++n ) {
00961 if ( helper->containsPrefix( parts[ rightOffset - n ].lower() ) ) {
00962 inclusionList.prepend( parts[ rightOffset - n ] );
00963 } else
00964 break;
00965 }
00966
00967 if ( !inclusionList.isEmpty() ) {
00968 setFamilyName( inclusionList.join( " " ) + spaceStr + parts[ rightOffset ] );
00969 rightOffset -= inclusionList.count();
00970 } else {
00971 if ( helper->tradeAsFamilyName() )
00972 setFamilyName( parts[ rightOffset ] );
00973 else
00974 setGivenName( parts[ rightOffset ] );
00975 }
00976
00977 QString prefix;
00978 while ( leftOffset < rightOffset ) {
00979 if ( helper->containsTitle( parts[ leftOffset ] ) ) {
00980 prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00981 leftOffset++;
00982 } else
00983 break;
00984 }
00985 setPrefix( prefix );
00986
00987 if ( leftOffset < rightOffset ) {
00988 setGivenName( parts[ leftOffset ] );
00989 leftOffset++;
00990 }
00991
00992 QString additionalName;
00993 while ( leftOffset < rightOffset ) {
00994 additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
00995 leftOffset++;
00996 }
00997 setAdditionalName( additionalName );
00998 } else {
00999 QString part1 = str.left( i );
01000 QString part2 = str.mid( i + 1 );
01001
01002 QStringList parts = QStringList::split( spaceStr, part1 );
01003 int leftOffset = 0;
01004 int rightOffset = parts.count() - 1;
01005
01006 if ( parts.count() > 0 ) {
01007
01008 QString suffix;
01009 while ( rightOffset >= 0 ) {
01010 if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
01011 suffix.prepend(parts[ rightOffset ] + (suffix.isEmpty() ? emptyStr : spaceStr));
01012 rightOffset--;
01013 } else
01014 break;
01015 }
01016 setSuffix( suffix );
01017
01018 if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].lower() ) ) {
01019 setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
01020 rightOffset--;
01021 } else
01022 setFamilyName( parts[ rightOffset ] );
01023
01024 QString prefix;
01025 while ( leftOffset < rightOffset ) {
01026 if ( helper->containsTitle( parts[ leftOffset ] ) ) {
01027 prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
01028 leftOffset++;
01029 } else
01030 break;
01031 }
01032 } else {
01033 setPrefix( "" );
01034 setFamilyName( "" );
01035 setSuffix( "" );
01036 }
01037
01038 parts = QStringList::split( spaceStr, part2 );
01039
01040 leftOffset = 0;
01041 rightOffset = parts.count();
01042
01043 if ( parts.count() > 0 ) {
01044
01045 QString prefix;
01046 while ( leftOffset < rightOffset ) {
01047 if ( helper->containsTitle( parts[ leftOffset ] ) ) {
01048 prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
01049 leftOffset++;
01050 } else
01051 break;
01052 }
01053 setPrefix( prefix );
01054
01055 if ( leftOffset < rightOffset ) {
01056 setGivenName( parts[ leftOffset ] );
01057 leftOffset++;
01058 }
01059
01060 QString additionalName;
01061 while ( leftOffset < rightOffset ) {
01062 additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr) + parts[ leftOffset ] );
01063 leftOffset++;
01064 }
01065 setAdditionalName( additionalName );
01066 } else {
01067 setGivenName( "" );
01068 setAdditionalName( "" );
01069 }
01070 }
01071 }
01072
01073 QString Addressee::realName() const
01074 {
01075 QString n( formattedName() );
01076 if ( !n.isEmpty() )
01077 return n;
01078
01079 n = assembledName();
01080 if ( !n.isEmpty() )
01081 return n;
01082
01083 n = name();
01084 if ( !n.isEmpty() )
01085 return n;
01086
01087 return organization();
01088 }
01089
01090 QString Addressee::assembledName() const
01091 {
01092 QString name = prefix() + " " + givenName() + " " + additionalName() + " " +
01093 familyName() + " " + suffix();
01094
01095 return name.simplifyWhiteSpace();
01096 }
01097
01098 QString Addressee::fullEmail( const QString &email ) const
01099 {
01100 QString e;
01101 if ( email.isNull() ) {
01102 e = preferredEmail();
01103 } else {
01104 e = email;
01105 }
01106 if ( e.isEmpty() ) return QString::null;
01107
01108 QString text;
01109 if ( realName().isEmpty() )
01110 text = e;
01111 else {
01112 QRegExp needQuotes( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" );
01113 if ( realName().find( needQuotes ) != -1 )
01114 text = "\"" + realName() + "\" <" + e + ">";
01115 else
01116 text = realName() + " <" + e + ">";
01117 }
01118
01119 return text;
01120 }
01121
01122 void Addressee::insertEmail( const QString &email, bool preferred )
01123 {
01124 if ( email.simplifyWhiteSpace().isEmpty() )
01125 return;
01126
01127 detach();
01128 mData->empty = false;
01129
01130 QStringList::Iterator it = mData->emails.find( email );
01131
01132 if ( it != mData->emails.end() ) {
01133 if ( !preferred || it == mData->emails.begin() ) return;
01134 mData->emails.remove( it );
01135 mData->emails.prepend( email );
01136 } else {
01137 if ( preferred ) {
01138 mData->emails.prepend( email );
01139 } else {
01140 mData->emails.append( email );
01141 }
01142 }
01143 }
01144
01145 void Addressee::removeEmail( const QString &email )
01146 {
01147 detach();
01148
01149 QStringList::Iterator it = mData->emails.find( email );
01150 if ( it == mData->emails.end() ) return;
01151
01152 mData->emails.remove( it );
01153 }
01154
01155 QString Addressee::preferredEmail() const
01156 {
01157 if ( mData->emails.count() == 0 ) return QString::null;
01158 else return mData->emails.first();
01159 }
01160
01161 QStringList Addressee::emails() const
01162 {
01163 return mData->emails;
01164 }
01165 void Addressee::setEmails( const QStringList& emails ) {
01166 detach();
01167
01168 mData->emails = emails;
01169 }
01170 void Addressee::insertPhoneNumber( const PhoneNumber &phoneNumber )
01171 {
01172 detach();
01173 mData->empty = false;
01174
01175 PhoneNumber::List::Iterator it;
01176 for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) {
01177 if ( (*it).id() == phoneNumber.id() ) {
01178 *it = phoneNumber;
01179 return;
01180 }
01181 }
01182 if ( !phoneNumber.number().simplifyWhiteSpace().isEmpty() )
01183 mData->phoneNumbers.append( phoneNumber );
01184 }
01185
01186 void Addressee::removePhoneNumber( const PhoneNumber &phoneNumber )
01187 {
01188 detach();
01189
01190 PhoneNumber::List::Iterator it;
01191 for( it = mData->phoneNumbers.begin(); it != mData->phoneNumbers.end(); ++it ) {
01192 if ( (*it).id() == phoneNumber.id() ) {
01193 mData->phoneNumbers.remove( it );
01194 return;
01195 }
01196 }
01197 }
01198
01199 PhoneNumber Addressee::phoneNumber( int type ) const
01200 {
01201 PhoneNumber phoneNumber( "", type );
01202 PhoneNumber::List::ConstIterator it;
01203 for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) {
01204 if ( matchBinaryPattern( (*it).type(), type ) ) {
01205 if ( (*it).type() & PhoneNumber::Pref )
01206 return (*it);
01207 else if ( phoneNumber.number().isEmpty() )
01208 phoneNumber = (*it);
01209 }
01210 }
01211
01212 return phoneNumber;
01213 }
01214
01215 PhoneNumber::List Addressee::phoneNumbers() const
01216 {
01217 return mData->phoneNumbers;
01218 }
01219
01220 PhoneNumber::List Addressee::phoneNumbers( int type ) const
01221 {
01222 PhoneNumber::List list;
01223
01224 PhoneNumber::List::ConstIterator it;
01225 for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) {
01226 if ( matchBinaryPattern( (*it).type(), type ) ) {
01227 list.append( *it );
01228 }
01229 }
01230 return list;
01231 }
01232
01233 PhoneNumber Addressee::findPhoneNumber( const QString &id ) const
01234 {
01235 PhoneNumber::List::ConstIterator it;
01236 for( it = mData->phoneNumbers.constBegin(); it != mData->phoneNumbers.constEnd(); ++it ) {
01237 if ( (*it).id() == id ) {
01238 return *it;
01239 }
01240 }
01241 return PhoneNumber();
01242 }
01243
01244 void Addressee::insertKey( const Key &key )
01245 {
01246 detach();
01247 mData->empty = false;
01248
01249 Key::List::Iterator it;
01250 for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) {
01251 if ( (*it).id() == key.id() ) {
01252 *it = key;
01253 return;
01254 }
01255 }
01256 mData->keys.append( key );
01257 }
01258
01259 void Addressee::removeKey( const Key &key )
01260 {
01261 detach();
01262
01263 Key::List::Iterator it;
01264 for( it = mData->keys.begin(); it != mData->keys.end(); ++it ) {
01265 if ( (*it).id() == key.id() ) {
01266 mData->keys.remove( key );
01267 return;
01268 }
01269 }
01270 }
01271
01272 Key Addressee::key( int type, QString customTypeString ) const
01273 {
01274 Key::List::ConstIterator it;
01275 for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) {
01276 if ( (*it).type() == type ) {
01277 if ( type == Key::Custom ) {
01278 if ( customTypeString.isEmpty() ) {
01279 return *it;
01280 } else {
01281 if ( (*it).customTypeString() == customTypeString )
01282 return (*it);
01283 }
01284 } else {
01285 return *it;
01286 }
01287 }
01288 }
01289 return Key( QString(), type );
01290 }
01291
01292 void Addressee::setKeys( const Key::List& list )
01293 {
01294 detach();
01295 mData->keys = list;
01296 }
01297
01298 Key::List Addressee::keys() const
01299 {
01300 return mData->keys;
01301 }
01302
01303 Key::List Addressee::keys( int type, QString customTypeString ) const
01304 {
01305 Key::List list;
01306
01307 Key::List::ConstIterator it;
01308 for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) {
01309 if ( (*it).type() == type ) {
01310 if ( type == Key::Custom ) {
01311 if ( customTypeString.isEmpty() ) {
01312 list.append( *it );
01313 } else {
01314 if ( (*it).customTypeString() == customTypeString )
01315 list.append( *it );
01316 }
01317 } else {
01318 list.append( *it );
01319 }
01320 }
01321 }
01322 return list;
01323 }
01324
01325 Key Addressee::findKey( const QString &id ) const
01326 {
01327 Key::List::ConstIterator it;
01328 for( it = mData->keys.constBegin(); it != mData->keys.constEnd(); ++it ) {
01329 if ( (*it).id() == id ) {
01330 return *it;
01331 }
01332 }
01333 return Key();
01334 }
01335
01336 QString Addressee::asString() const
01337 {
01338 return "Smith, agent Smith...";
01339 }
01340
01341 void Addressee::dump() const
01342 {
01343 kdDebug(5700) << "Addressee {" << endl;
01344
01345 kdDebug(5700) << " Uid: '" << uid() << "'" << endl;
01346
01347 kdDebug(5700) << " Name: '" << name() << "'" << endl;
01348 kdDebug(5700) << " FormattedName: '" << formattedName() << "'" << endl;
01349 kdDebug(5700) << " FamilyName: '" << familyName() << "'" << endl;
01350 kdDebug(5700) << " GivenName: '" << givenName() << "'" << endl;
01351 kdDebug(5700) << " AdditionalName: '" << additionalName() << "'" << endl;
01352 kdDebug(5700) << " Prefix: '" << prefix() << "'" << endl;
01353 kdDebug(5700) << " Suffix: '" << suffix() << "'" << endl;
01354 kdDebug(5700) << " NickName: '" << nickName() << "'" << endl;
01355 kdDebug(5700) << " Birthday: '" << birthday().toString() << "'" << endl;
01356 kdDebug(5700) << " Mailer: '" << mailer() << "'" << endl;
01357 kdDebug(5700) << " TimeZone: '" << timeZone().asString() << "'" << endl;
01358 kdDebug(5700) << " Geo: '" << geo().asString() << "'" << endl;
01359 kdDebug(5700) << " Title: '" << title() << "'" << endl;
01360 kdDebug(5700) << " Role: '" << role() << "'" << endl;
01361 kdDebug(5700) << " Organization: '" << organization() << "'" << endl;
01362 kdDebug(5700) << " Note: '" << note() << "'" << endl;
01363 kdDebug(5700) << " ProductId: '" << productId() << "'" << endl;
01364 kdDebug(5700) << " Revision: '" << revision().toString() << "'" << endl;
01365 kdDebug(5700) << " SortString: '" << sortString() << "'" << endl;
01366 kdDebug(5700) << " Url: '" << url().url() << "'" << endl;
01367 kdDebug(5700) << " Secrecy: '" << secrecy().asString() << "'" << endl;
01368 kdDebug(5700) << " Logo: '" << logo().asString() << "'" << endl;
01369 kdDebug(5700) << " Photo: '" << photo().asString() << "'" << endl;
01370 kdDebug(5700) << " Sound: '" << sound().asString() << "'" << endl;
01371 kdDebug(5700) << " Agent: '" << agent().asString() << "'" << endl;
01372
01373 kdDebug(5700) << " Emails {" << endl;
01374 const QStringList e = emails();
01375 QStringList::ConstIterator it;
01376 for( it = e.begin(); it != e.end(); ++it ) {
01377 kdDebug(5700) << " " << (*it) << endl;
01378 }
01379 kdDebug(5700) << " }" << endl;
01380
01381 kdDebug(5700) << " PhoneNumbers {" << endl;
01382 const PhoneNumber::List p = phoneNumbers();
01383 PhoneNumber::List::ConstIterator it2;
01384 for( it2 = p.begin(); it2 != p.end(); ++it2 ) {
01385 kdDebug(5700) << " Type: " << int((*it2).type()) << " Number: " << (*it2).number() << endl;
01386 }
01387 kdDebug(5700) << " }" << endl;
01388
01389 const Address::List a = addresses();
01390 Address::List::ConstIterator it3;
01391 for( it3 = a.begin(); it3 != a.end(); ++it3 ) {
01392 (*it3).dump();
01393 }
01394
01395 kdDebug(5700) << " Keys {" << endl;
01396 const Key::List k = keys();
01397 Key::List::ConstIterator it4;
01398 for( it4 = k.begin(); it4 != k.end(); ++it4 ) {
01399 kdDebug(5700) << " Type: " << int((*it4).type()) <<
01400 " Key: " << (*it4).textData() <<
01401 " CustomString: " << (*it4).customTypeString() << endl;
01402 }
01403 kdDebug(5700) << " }" << endl;
01404
01405 kdDebug(5700) << "}" << endl;
01406 }
01407
01408
01409 void Addressee::insertAddress( const Address &address )
01410 {
01411 if ( address.isEmpty() )
01412 return;
01413
01414 detach();
01415 mData->empty = false;
01416
01417 Address::List::Iterator it;
01418 for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) {
01419 if ( (*it).id() == address.id() ) {
01420 *it = address;
01421 return;
01422 }
01423 }
01424
01425 mData->addresses.append( address );
01426 }
01427
01428 void Addressee::removeAddress( const Address &address )
01429 {
01430 detach();
01431
01432 Address::List::Iterator it;
01433 for( it = mData->addresses.begin(); it != mData->addresses.end(); ++it ) {
01434 if ( (*it).id() == address.id() ) {
01435 mData->addresses.remove( it );
01436 return;
01437 }
01438 }
01439 }
01440
01441 Address Addressee::address( int type ) const
01442 {
01443 Address address( type );
01444 Address::List::ConstIterator it;
01445 for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) {
01446 if ( matchBinaryPattern( (*it).type(), type ) ) {
01447 if ( (*it).type() & Address::Pref )
01448 return (*it);
01449 else if ( address.isEmpty() )
01450 address = (*it);
01451 }
01452 }
01453
01454 return address;
01455 }
01456
01457 Address::List Addressee::addresses() const
01458 {
01459 return mData->addresses;
01460 }
01461
01462 Address::List Addressee::addresses( int type ) const
01463 {
01464 Address::List list;
01465
01466 Address::List::ConstIterator it;
01467 for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) {
01468 if ( matchBinaryPattern( (*it).type(), type ) ) {
01469 list.append( *it );
01470 }
01471 }
01472
01473 return list;
01474 }
01475
01476 Address Addressee::findAddress( const QString &id ) const
01477 {
01478 Address::List::ConstIterator it;
01479 for( it = mData->addresses.constBegin(); it != mData->addresses.constEnd(); ++it ) {
01480 if ( (*it).id() == id ) {
01481 return *it;
01482 }
01483 }
01484 return Address();
01485 }
01486
01487 void Addressee::insertCategory( const QString &c )
01488 {
01489 detach();
01490 mData->empty = false;
01491
01492 if ( mData->categories.findIndex( c ) != -1 ) return;
01493
01494 mData->categories.append( c );
01495 }
01496
01497 void Addressee::removeCategory( const QString &c )
01498 {
01499 detach();
01500
01501 QStringList::Iterator it = mData->categories.find( c );
01502 if ( it == mData->categories.end() ) return;
01503
01504 mData->categories.remove( it );
01505 }
01506
01507 bool Addressee::hasCategory( const QString &c ) const
01508 {
01509 return ( mData->categories.findIndex( c ) != -1 );
01510 }
01511
01512 void Addressee::setCategories( const QStringList &c )
01513 {
01514 detach();
01515 mData->empty = false;
01516
01517 mData->categories = c;
01518 }
01519
01520 QStringList Addressee::categories() const
01521 {
01522 return mData->categories;
01523 }
01524
01525 void Addressee::insertCustom( const QString &app, const QString &name,
01526 const QString &value )
01527 {
01528 if ( value.isEmpty() || name.isEmpty() || app.isEmpty() ) return;
01529
01530 detach();
01531 mData->empty = false;
01532
01533 QString qualifiedName = app + "-" + name + ":";
01534
01535 QStringList::Iterator it;
01536 for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) {
01537 if ( (*it).startsWith( qualifiedName ) ) {
01538 (*it) = qualifiedName + value;
01539 return;
01540 }
01541 }
01542
01543 mData->custom.append( qualifiedName + value );
01544 }
01545
01546 void Addressee::removeCustom( const QString &app, const QString &name)
01547 {
01548 detach();
01549
01550 QString qualifiedName = app + "-" + name + ":";
01551
01552 QStringList::Iterator it;
01553 for( it = mData->custom.begin(); it != mData->custom.end(); ++it ) {
01554 if ( (*it).startsWith( qualifiedName ) ) {
01555 mData->custom.remove( it );
01556 return;
01557 }
01558 }
01559 }
01560
01561 QString Addressee::custom( const QString &app, const QString &name ) const
01562 {
01563 QString qualifiedName = app + "-" + name + ":";
01564 QString value;
01565
01566 QStringList::ConstIterator it;
01567 for( it = mData->custom.constBegin(); it != mData->custom.constEnd(); ++it ) {
01568 if ( (*it).startsWith( qualifiedName ) ) {
01569 value = (*it).mid( (*it).find( ":" ) + 1 );
01570 break;
01571 }
01572 }
01573
01574 return value;
01575 }
01576
01577 void Addressee::setCustoms( const QStringList &l )
01578 {
01579 detach();
01580 mData->empty = false;
01581
01582 mData->custom = l;
01583 }
01584
01585 QStringList Addressee::customs() const
01586 {
01587 return mData->custom;
01588 }
01589
01590 void Addressee::parseEmailAddress( const QString &rawEmail, QString &fullName,
01591 QString &email)
01592 {
01593
01594
01595 fullName = "";
01596 email = "";
01597 if ( rawEmail.isEmpty() )
01598 return;
01599
01600
01601 QCString address = rawEmail.utf8();
01602
01603 QCString displayName;
01604 QCString addrSpec;
01605 QCString comment;
01606
01607
01608
01609
01610
01611 enum { TopLevel, InComment, InAngleAddress } context = TopLevel;
01612 bool inQuotedString = false;
01613 int commentLevel = 0;
01614 bool stop = false;
01615
01616 for ( char* p = address.data(); *p && !stop; ++p ) {
01617 switch ( context ) {
01618 case TopLevel : {
01619 switch ( *p ) {
01620 case '"' : inQuotedString = !inQuotedString;
01621 displayName += *p;
01622 break;
01623 case '(' : if ( !inQuotedString ) {
01624 context = InComment;
01625 commentLevel = 1;
01626 }
01627 else
01628 displayName += *p;
01629 break;
01630 case '<' : if ( !inQuotedString ) {
01631 context = InAngleAddress;
01632 }
01633 else
01634 displayName += *p;
01635 break;
01636 case '\\' :
01637 displayName += *p;
01638 ++p;
01639 if ( *p )
01640 displayName += *p;
01641 else
01642
01643 goto ABORT_PARSING;
01644 break;
01645 case ',' : if ( !inQuotedString ) {
01646
01647
01648
01649
01650 goto ABORT_PARSING;
01651 }
01652 else
01653 displayName += *p;
01654 break;
01655 default : displayName += *p;
01656 }
01657 break;
01658 }
01659 case InComment : {
01660 switch ( *p ) {
01661 case '(' : ++commentLevel;
01662 comment += *p;
01663 break;
01664 case ')' : --commentLevel;
01665 if ( commentLevel == 0 ) {
01666 context = TopLevel;
01667 comment += ' ';
01668 }
01669 else
01670 comment += *p;
01671 break;
01672 case '\\' :
01673 comment += *p;
01674 ++p;
01675 if ( *p )
01676 comment += *p;
01677 else
01678
01679 goto ABORT_PARSING;
01680 break;
01681 default : comment += *p;
01682 }
01683 break;
01684 }
01685 case InAngleAddress : {
01686 switch ( *p ) {
01687 case '"' : inQuotedString = !inQuotedString;
01688 addrSpec += *p;
01689 break;
01690 case '>' : if ( !inQuotedString ) {
01691 context = TopLevel;
01692 }
01693 else
01694 addrSpec += *p;
01695 break;
01696 case '\\' :
01697 addrSpec += *p;
01698 ++p;
01699 if ( *p )
01700 addrSpec += *p;
01701 else
01702
01703 goto ABORT_PARSING;
01704 break;
01705 default : addrSpec += *p;
01706 }
01707 break;
01708 }
01709 }
01710 }
01711
01712 ABORT_PARSING:
01713 displayName = displayName.stripWhiteSpace();
01714 comment = comment.stripWhiteSpace();
01715 addrSpec = addrSpec.stripWhiteSpace();
01716
01717 fullName = QString::fromUtf8( displayName );
01718 email = QString::fromUtf8( addrSpec );
01719
01720
01721 if ( inQuotedString )
01722 return;
01723 if ( context == InComment )
01724 return;
01725 if ( context == InAngleAddress )
01726 return;
01727
01728 if ( addrSpec.isEmpty() ) {
01729 if ( displayName.isEmpty() )
01730 return;
01731 else {
01732
01733
01734
01735 email = fullName;
01736 fullName = QString::fromUtf8( comment );
01737 }
01738 }
01739
01740
01741
01742 unsigned int len = fullName.length();
01743 if ( fullName[ 0 ] == '"' && fullName[ len - 1 ] == '"' )
01744 fullName = fullName.mid( 1, len - 2 );
01745 }
01746
01747 void Addressee::setResource( Resource *resource )
01748 {
01749 detach();
01750 mData->resource = resource;
01751 }
01752
01753 Resource *Addressee::resource() const
01754 {
01755 return mData->resource;
01756 }
01757
01758 void Addressee::setChanged( bool value )
01759 {
01760 detach();
01761 mData->changed = value;
01762 }
01763
01764 bool Addressee::changed() const
01765 {
01766 return mData->changed;
01767 }
01768
01769 void Addressee::setSortMode( KABC::SortMode *mode )
01770 {
01771 mSortMode = mode;
01772 }
01773
01774 bool Addressee::operator< ( const Addressee &addr )
01775 {
01776 if ( !mSortMode )
01777 return false;
01778 else
01779 return mSortMode->lesser( *this, addr );
01780 }
01781
01782 QDataStream &KABC::operator<<( QDataStream &s, const Addressee &a )
01783 {
01784 if (!a.mData) return s;
01785
01786 s << a.uid();
01787
01788 s << a.mData->name;
01789 s << a.mData->formattedName;
01790 s << a.mData->familyName;
01791 s << a.mData->givenName;
01792 s << a.mData->additionalName;
01793 s << a.mData->prefix;
01794 s << a.mData->suffix;
01795 s << a.mData->nickName;
01796 s << a.mData->birthday;
01797 s << a.mData->mailer;
01798 s << a.mData->timeZone;
01799 s << a.mData->geo;
01800 s << a.mData->title;
01801 s << a.mData->role;
01802 s << a.mData->organization;
01803 s << a.mData->note;
01804 s << a.mData->productId;
01805 s << a.mData->revision;
01806 s << a.mData->sortString;
01807 s << a.mData->url;
01808 s << a.mData->secrecy;
01809 s << a.mData->logo;
01810 s << a.mData->photo;
01811 s << a.mData->sound;
01812 s << a.mData->agent;
01813 s << a.mData->phoneNumbers;
01814 s << a.mData->addresses;
01815 s << a.mData->emails;
01816 s << a.mData->categories;
01817 s << a.mData->custom;
01818 s << a.mData->keys;
01819 return s;
01820 }
01821
01822 QDataStream &KABC::operator>>( QDataStream &s, Addressee &a )
01823 {
01824 if (!a.mData)
01825 return s;
01826
01827 a.detach();
01828
01829 s >> a.mData->uid;
01830
01831 s >> a.mData->name;
01832 s >> a.mData->formattedName;
01833 s >> a.mData->familyName;
01834 s >> a.mData->givenName;
01835 s >> a.mData->additionalName;
01836 s >> a.mData->prefix;
01837 s >> a.mData->suffix;
01838 s >> a.mData->nickName;
01839 s >> a.mData->birthday;
01840 s >> a.mData->mailer;
01841 s >> a.mData->timeZone;
01842 s >> a.mData->geo;
01843 s >> a.mData->title;
01844 s >> a.mData->role;
01845 s >> a.mData->organization;
01846 s >> a.mData->note;
01847 s >> a.mData->productId;
01848 s >> a.mData->revision;
01849 s >> a.mData->sortString;
01850 s >> a.mData->url;
01851 s >> a.mData->secrecy;
01852 s >> a.mData->logo;
01853 s >> a.mData->photo;
01854 s >> a.mData->sound;
01855 s >> a.mData->agent;
01856 s >> a.mData->phoneNumbers;
01857 s >> a.mData->addresses;
01858 s >> a.mData->emails;
01859 s >> a.mData->categories;
01860 s >> a.mData->custom;
01861 s >> a.mData->keys;
01862
01863 a.mData->empty = false;
01864
01865 return s;
01866 }
01867
01868 bool matchBinaryPattern( int value, int pattern )
01869 {
01876 if ( pattern == 0 )
01877 return ( value == 0 );
01878 else
01879 return ( pattern == ( pattern & value ) );
01880 }
01881
01882 template <class L>
01883 bool listEquals( const QValueList<L> &list, const QValueList<L> &pattern )
01884 {
01885 if ( list.count() != pattern.count() )
01886 return false;
01887
01888 for ( uint i = 0; i < list.count(); ++i )
01889 if ( pattern.find( list[ i ] ) == pattern.end() )
01890 return false;
01891
01892 return true;
01893 }
01894
01895 bool emailsEquals( const QStringList &list, const QStringList &pattern )
01896 {
01897 if ( list.count() != pattern.count() )
01898 return false;
01899
01900 if ( list.first() != pattern.first() )
01901 return false;
01902
01903 QStringList::ConstIterator it;
01904 for ( it = list.begin(); it != list.end(); ++it )
01905 if ( pattern.find( *it ) == pattern.end() )
01906 return false;
01907
01908 return true;
01909 }