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