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