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