mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
2028 lines
44 KiB
C++
2028 lines
44 KiB
C++
/*
|
|
This file is part of libkabc.
|
|
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
|
|
Copyright (c) 2003 Carsten Pfeiffer <pfeiffer@kde.org>
|
|
Copyright (c) 2005 Ingo Kloecker <kloecker@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <QtCore/QList>
|
|
#include <QtCore/QRegExp>
|
|
#include <QtCore/QSharedData>
|
|
#include <QtCore/QUuid>
|
|
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
#include <klocalizedstring.h>
|
|
|
|
#include "addresseehelper.h"
|
|
#include "field.h"
|
|
#ifndef KDEPIM_NO_KRESOURCES
|
|
#include "resource.h"
|
|
#endif
|
|
#include "sortmode.h"
|
|
|
|
#include "addressee.h"
|
|
|
|
using namespace KABC;
|
|
|
|
static bool matchBinaryPattern( int value, int pattern );
|
|
|
|
template <class L>
|
|
static bool listEquals( const QList<L>&, const QList<L>& );
|
|
static bool listEquals( const QStringList&, const QStringList& );
|
|
static bool emailsEquals( const QStringList&, const QStringList& );
|
|
|
|
class Addressee::Private : public QSharedData
|
|
{
|
|
public:
|
|
Private()
|
|
: mUid( QUuid::createUuid().toString().mid(1, 36) ), //We avoid the curly braces so the string is RFC4122 compliant and can be used as urn
|
|
#ifndef KDEPIM_NO_KRESOURCES
|
|
mResource( 0 ),
|
|
#endif
|
|
mEmpty( true ), mChanged( false )
|
|
{
|
|
}
|
|
|
|
Private( const Private &other )
|
|
: QSharedData( other )
|
|
#ifndef KDEPIM_NO_KRESOURCES
|
|
,mResource( 0 )
|
|
#endif
|
|
{
|
|
mUid = other.mUid;
|
|
mName = other.mName;
|
|
mFormattedName = other.mFormattedName;
|
|
mFamilyName = other.mFamilyName;
|
|
mGivenName = other.mGivenName;
|
|
mAdditionalName = other.mAdditionalName;
|
|
mPrefix = other.mPrefix;
|
|
mSuffix = other.mSuffix;
|
|
mNickName = other.mNickName;
|
|
mBirthday = other.mBirthday;
|
|
mMailer = other.mMailer;
|
|
mTimeZone = other.mTimeZone;
|
|
mGeo = other.mGeo;
|
|
mTitle = other.mTitle;
|
|
mRole = other.mRole;
|
|
mOrganization = other.mOrganization;
|
|
mDepartment = other.mDepartment;
|
|
mNote = other.mNote;
|
|
mProductId = other.mProductId;
|
|
mRevision = other.mRevision;
|
|
mSortString = other.mSortString;
|
|
mUrl = other.mUrl;
|
|
mSecrecy = other.mSecrecy;
|
|
mLogo = other.mLogo;
|
|
mPhoto = other.mPhoto;
|
|
mSound = other.mSound;
|
|
|
|
mPhoneNumbers = other.mPhoneNumbers;
|
|
mAddresses = other.mAddresses;
|
|
mKeys = other.mKeys;
|
|
mEmails = other.mEmails;
|
|
mCategories = other.mCategories;
|
|
mCustomFields = other.mCustomFields;
|
|
|
|
#ifndef KDEPIM_NO_KRESOURCES
|
|
mResource = other.mResource;
|
|
#endif
|
|
mEmpty = other.mEmpty;
|
|
mChanged = other.mChanged;
|
|
}
|
|
|
|
~Private()
|
|
{
|
|
}
|
|
|
|
QString mUid;
|
|
QString mName;
|
|
QString mFormattedName;
|
|
QString mFamilyName;
|
|
QString mGivenName;
|
|
QString mAdditionalName;
|
|
QString mPrefix;
|
|
QString mSuffix;
|
|
QString mNickName;
|
|
QDateTime mBirthday;
|
|
QString mMailer;
|
|
TimeZone mTimeZone;
|
|
Geo mGeo;
|
|
QString mTitle;
|
|
QString mRole;
|
|
QString mOrganization;
|
|
QString mDepartment;
|
|
QString mNote;
|
|
QString mProductId;
|
|
QDateTime mRevision;
|
|
QString mSortString;
|
|
KUrl mUrl;
|
|
Secrecy mSecrecy;
|
|
Picture mLogo;
|
|
Picture mPhoto;
|
|
Sound mSound;
|
|
|
|
PhoneNumber::List mPhoneNumbers;
|
|
Address::List mAddresses;
|
|
Key::List mKeys;
|
|
QStringList mEmails;
|
|
QStringList mCategories;
|
|
QMap<QString, QString> mCustomFields;
|
|
|
|
#ifndef KDEPIM_NO_KRESOURCES
|
|
Resource *mResource;
|
|
#endif
|
|
|
|
bool mEmpty :1;
|
|
bool mChanged :1;
|
|
|
|
static KABC::SortMode *mSortMode;
|
|
};
|
|
|
|
KABC::SortMode *Addressee::Private::mSortMode = 0;
|
|
|
|
Addressee::Addressee()
|
|
: d( new Private )
|
|
{
|
|
}
|
|
|
|
Addressee::~Addressee()
|
|
{
|
|
}
|
|
|
|
Addressee::Addressee( const Addressee &other )
|
|
: d( other.d )
|
|
{
|
|
}
|
|
|
|
Addressee& Addressee::operator=( const Addressee &other )
|
|
{
|
|
if ( this != &other )
|
|
d = other.d;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool Addressee::operator==( const Addressee &addressee ) const
|
|
{
|
|
if ( d->mUid != addressee.d->mUid ) {
|
|
kDebug() << "uid differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mName != addressee.d->mName &&
|
|
!( d->mName.isEmpty() && addressee.d->mName.isEmpty() ) ) {
|
|
kDebug(5700) << "name differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mFormattedName != addressee.d->mFormattedName &&
|
|
!( d->mFormattedName.isEmpty() && addressee.d->mFormattedName.isEmpty() ) ) {
|
|
kDebug(5700) << "formattedName differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mFamilyName != addressee.d->mFamilyName &&
|
|
!( d->mFamilyName.isEmpty() && addressee.d->mFamilyName.isEmpty() ) ) {
|
|
kDebug(5700) << "familyName differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mGivenName != addressee.d->mGivenName &&
|
|
!( d->mGivenName.isEmpty() && addressee.d->mGivenName.isEmpty() ) ) {
|
|
kDebug(5700) << "givenName differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mAdditionalName != addressee.d->mAdditionalName &&
|
|
!( d->mAdditionalName.isEmpty() && addressee.d->mAdditionalName.isEmpty() ) ) {
|
|
kDebug(5700) << "additionalName differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mPrefix != addressee.d->mPrefix &&
|
|
!( d->mPrefix.isEmpty() && addressee.d->mPrefix.isEmpty() ) ) {
|
|
kDebug(5700) << "prefix differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mSuffix != addressee.d->mSuffix &&
|
|
!( d->mSuffix.isEmpty() && addressee.d->mSuffix.isEmpty() ) ) {
|
|
kDebug(5700) << "suffix differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mNickName != addressee.d->mNickName &&
|
|
!( d->mNickName.isEmpty() && addressee.d->mNickName.isEmpty() ) ) {
|
|
kDebug(5700) << "nickName differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mBirthday != addressee.d->mBirthday ) {
|
|
kDebug(5700) << "birthday differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mMailer != addressee.d->mMailer &&
|
|
!( d->mMailer.isEmpty() && addressee.d->mMailer.isEmpty() ) ) {
|
|
kDebug(5700) << "mailer differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mTimeZone != addressee.d->mTimeZone ) {
|
|
kDebug(5700) << "timeZone differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mGeo != addressee.d->mGeo ) {
|
|
kDebug(5700) << "geo differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mTitle != addressee.d->mTitle &&
|
|
!( d->mTitle.isEmpty() && addressee.d->mTitle.isEmpty() ) ) {
|
|
kDebug(5700) << "title differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mRole != addressee.d->mRole &&
|
|
!( d->mRole.isEmpty() && addressee.d->mRole.isEmpty() ) ) {
|
|
kDebug(5700) << "role differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mOrganization != addressee.d->mOrganization &&
|
|
!( d->mOrganization.isEmpty() && addressee.d->mOrganization.isEmpty() ) ) {
|
|
kDebug(5700) << "organization differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mDepartment != addressee.d->mDepartment &&
|
|
!( d->mDepartment.isEmpty() && addressee.d->mDepartment.isEmpty() ) ) {
|
|
kDebug(5700) << "department differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mNote != addressee.d->mNote &&
|
|
!( d->mNote.isEmpty() && addressee.d->mNote.isEmpty() ) ) {
|
|
kDebug(5700) << "note differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mProductId != addressee.d->mProductId &&
|
|
!( d->mProductId.isEmpty() && addressee.d->mProductId.isEmpty() ) ) {
|
|
kDebug(5700) << "productId differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mSortString != addressee.d->mSortString &&
|
|
!( d->mSortString.isEmpty() && addressee.d->mSortString.isEmpty() ) ) {
|
|
kDebug(5700) << "sortString differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mSecrecy != addressee.d->mSecrecy ) {
|
|
kDebug(5700) << "secrecy differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mLogo != addressee.d->mLogo ) {
|
|
kDebug(5700) << "logo differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mPhoto != addressee.d->mPhoto ) {
|
|
kDebug(5700) << "photo differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mSound != addressee.d->mSound ) {
|
|
kDebug(5700) << "sound differs";
|
|
return false;
|
|
}
|
|
|
|
if ( ( d->mUrl.isValid() || addressee.d->mUrl.isValid() ) &&
|
|
( d->mUrl != addressee.d->mUrl ) ) {
|
|
kDebug() << "url differs";
|
|
return false;
|
|
}
|
|
|
|
if ( !listEquals( d->mPhoneNumbers, addressee.d->mPhoneNumbers ) ) {
|
|
kDebug() << "phoneNumbers differs";
|
|
return false;
|
|
}
|
|
|
|
if ( !listEquals( d->mAddresses, addressee.d->mAddresses ) ) {
|
|
kDebug() << "addresses differs";
|
|
return false;
|
|
}
|
|
|
|
if ( !listEquals( d->mKeys, addressee.d->mKeys ) ) {
|
|
kDebug() << "keys differs";
|
|
return false;
|
|
}
|
|
|
|
if ( !emailsEquals( d->mEmails, addressee.d->mEmails ) ) {
|
|
kDebug() << "emails differs";
|
|
return false;
|
|
}
|
|
|
|
if ( !listEquals( d->mCategories, addressee.d->mCategories ) ) {
|
|
kDebug() << "categories differs";
|
|
return false;
|
|
}
|
|
|
|
if ( d->mCustomFields != addressee.d->mCustomFields ) {
|
|
kDebug() << "custom differs";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Addressee::operator!=( const Addressee &a ) const
|
|
{
|
|
return !( a == *this );
|
|
}
|
|
|
|
bool Addressee::isEmpty() const
|
|
{
|
|
return d->mEmpty;
|
|
}
|
|
|
|
void Addressee::setUid( const QString &id )
|
|
{
|
|
if ( id == d->mUid )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mUid = id;
|
|
}
|
|
|
|
QString Addressee::uid() const
|
|
{
|
|
return d->mUid;
|
|
}
|
|
|
|
QString Addressee::uidLabel()
|
|
{
|
|
return i18n( "Unique Identifier" );
|
|
}
|
|
|
|
void Addressee::setName( const QString &name )
|
|
{
|
|
if ( name == d->mName )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mName = name;
|
|
}
|
|
|
|
QString Addressee::name() const
|
|
{
|
|
return d->mName;
|
|
}
|
|
|
|
QString Addressee::nameLabel()
|
|
{
|
|
return i18n( "Name" );
|
|
}
|
|
|
|
|
|
void Addressee::setFormattedName( const QString &formattedName )
|
|
{
|
|
if ( formattedName == d->mFormattedName )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mFormattedName = formattedName;
|
|
}
|
|
|
|
QString Addressee::formattedName() const
|
|
{
|
|
return d->mFormattedName;
|
|
}
|
|
|
|
QString Addressee::formattedNameLabel()
|
|
{
|
|
return i18n( "Formatted Name" );
|
|
}
|
|
|
|
|
|
void Addressee::setFamilyName( const QString &familyName )
|
|
{
|
|
if ( familyName == d->mFamilyName )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mFamilyName = familyName;
|
|
}
|
|
|
|
QString Addressee::familyName() const
|
|
{
|
|
return d->mFamilyName;
|
|
}
|
|
|
|
QString Addressee::familyNameLabel()
|
|
{
|
|
return i18n( "Family Name" );
|
|
}
|
|
|
|
|
|
void Addressee::setGivenName( const QString &givenName )
|
|
{
|
|
if ( givenName == d->mGivenName )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mGivenName = givenName;
|
|
}
|
|
|
|
QString Addressee::givenName() const
|
|
{
|
|
return d->mGivenName;
|
|
}
|
|
|
|
QString Addressee::givenNameLabel()
|
|
{
|
|
return i18n( "Given Name" );
|
|
}
|
|
|
|
|
|
void Addressee::setAdditionalName( const QString &additionalName )
|
|
{
|
|
if ( additionalName == d->mAdditionalName )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mAdditionalName = additionalName;
|
|
}
|
|
|
|
QString Addressee::additionalName() const
|
|
{
|
|
return d->mAdditionalName;
|
|
}
|
|
|
|
QString Addressee::additionalNameLabel()
|
|
{
|
|
return i18n( "Additional Names" );
|
|
}
|
|
|
|
|
|
void Addressee::setPrefix( const QString &prefix )
|
|
{
|
|
if ( prefix == d->mPrefix )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mPrefix = prefix;
|
|
}
|
|
|
|
QString Addressee::prefix() const
|
|
{
|
|
return d->mPrefix;
|
|
}
|
|
|
|
QString Addressee::prefixLabel()
|
|
{
|
|
return i18n( "Honorific Prefixes" );
|
|
}
|
|
|
|
|
|
void Addressee::setSuffix( const QString &suffix )
|
|
{
|
|
if ( suffix == d->mSuffix )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mSuffix = suffix;
|
|
}
|
|
|
|
QString Addressee::suffix() const
|
|
{
|
|
return d->mSuffix;
|
|
}
|
|
|
|
QString Addressee::suffixLabel()
|
|
{
|
|
return i18n( "Honorific Suffixes" );
|
|
}
|
|
|
|
|
|
void Addressee::setNickName( const QString &nickName )
|
|
{
|
|
if ( nickName == d->mNickName )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mNickName = nickName;
|
|
}
|
|
|
|
QString Addressee::nickName() const
|
|
{
|
|
return d->mNickName;
|
|
}
|
|
|
|
QString Addressee::nickNameLabel()
|
|
{
|
|
return i18n( "Nick Name" );
|
|
}
|
|
|
|
|
|
void Addressee::setBirthday( const QDateTime &birthday )
|
|
{
|
|
if ( birthday == d->mBirthday )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mBirthday = birthday;
|
|
}
|
|
|
|
QDateTime Addressee::birthday() const
|
|
{
|
|
return d->mBirthday;
|
|
}
|
|
|
|
QString Addressee::birthdayLabel()
|
|
{
|
|
return i18n( "Birthday" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressStreetLabel()
|
|
{
|
|
return i18n( "Home Address Street" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressPostOfficeBoxLabel()
|
|
{
|
|
return i18n( "Home Address Post Office Box" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressLocalityLabel()
|
|
{
|
|
return i18n( "Home Address City" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressRegionLabel()
|
|
{
|
|
return i18n( "Home Address State" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressPostalCodeLabel()
|
|
{
|
|
return i18n( "Home Address Zip Code" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressCountryLabel()
|
|
{
|
|
return i18n( "Home Address Country" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeAddressLabelLabel()
|
|
{
|
|
return i18n( "Home Address Label" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressStreetLabel()
|
|
{
|
|
return i18n( "Business Address Street" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressPostOfficeBoxLabel()
|
|
{
|
|
return i18n( "Business Address Post Office Box" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressLocalityLabel()
|
|
{
|
|
return i18n( "Business Address City" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressRegionLabel()
|
|
{
|
|
return i18n( "Business Address State" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressPostalCodeLabel()
|
|
{
|
|
return i18n( "Business Address Zip Code" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressCountryLabel()
|
|
{
|
|
return i18n( "Business Address Country" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessAddressLabelLabel()
|
|
{
|
|
return i18n( "Business Address Label" );
|
|
}
|
|
|
|
|
|
QString Addressee::homePhoneLabel()
|
|
{
|
|
return i18n( "Home Phone" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessPhoneLabel()
|
|
{
|
|
return i18n( "Business Phone" );
|
|
}
|
|
|
|
|
|
QString Addressee::mobilePhoneLabel()
|
|
{
|
|
return i18n( "Mobile Phone" );
|
|
}
|
|
|
|
|
|
QString Addressee::homeFaxLabel()
|
|
{
|
|
return i18n( "Home Fax" );
|
|
}
|
|
|
|
|
|
QString Addressee::businessFaxLabel()
|
|
{
|
|
return i18n( "Business Fax" );
|
|
}
|
|
|
|
|
|
QString Addressee::carPhoneLabel()
|
|
{
|
|
return i18n( "Car Phone" );
|
|
}
|
|
|
|
|
|
QString Addressee::isdnLabel()
|
|
{
|
|
return i18n( "ISDN" );
|
|
}
|
|
|
|
|
|
QString Addressee::pagerLabel()
|
|
{
|
|
return i18n( "Pager" );
|
|
}
|
|
|
|
|
|
QString Addressee::emailLabel()
|
|
{
|
|
return i18n( "Email Address" );
|
|
}
|
|
|
|
|
|
void Addressee::setMailer( const QString &mailer )
|
|
{
|
|
if ( mailer == d->mMailer )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mMailer = mailer;
|
|
}
|
|
|
|
QString Addressee::mailer() const
|
|
{
|
|
return d->mMailer;
|
|
}
|
|
|
|
QString Addressee::mailerLabel()
|
|
{
|
|
return i18n( "Mail Client" );
|
|
}
|
|
|
|
|
|
void Addressee::setTimeZone( const TimeZone &timeZone )
|
|
{
|
|
if ( timeZone == d->mTimeZone )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mTimeZone = timeZone;
|
|
}
|
|
|
|
TimeZone Addressee::timeZone() const
|
|
{
|
|
return d->mTimeZone;
|
|
}
|
|
|
|
QString Addressee::timeZoneLabel()
|
|
{
|
|
return i18n( "Time Zone" );
|
|
}
|
|
|
|
|
|
void Addressee::setGeo( const Geo &geo )
|
|
{
|
|
if ( geo == d->mGeo )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mGeo = geo;
|
|
}
|
|
|
|
Geo Addressee::geo() const
|
|
{
|
|
return d->mGeo;
|
|
}
|
|
|
|
QString Addressee::geoLabel()
|
|
{
|
|
return i18n( "Geographic Position" );
|
|
}
|
|
|
|
|
|
void Addressee::setTitle( const QString &title )
|
|
{
|
|
if ( title == d->mTitle )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mTitle = title;
|
|
}
|
|
|
|
QString Addressee::title() const
|
|
{
|
|
return d->mTitle;
|
|
}
|
|
|
|
QString Addressee::titleLabel()
|
|
{
|
|
return i18nc( "a person's title", "Title" );
|
|
}
|
|
|
|
|
|
void Addressee::setRole( const QString &role )
|
|
{
|
|
if ( role == d->mRole )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mRole = role;
|
|
}
|
|
|
|
QString Addressee::role() const
|
|
{
|
|
return d->mRole;
|
|
}
|
|
|
|
QString Addressee::roleLabel()
|
|
{
|
|
return i18nc( "of a person in an organization", "Role" );
|
|
}
|
|
|
|
|
|
void Addressee::setOrganization( const QString &organization )
|
|
{
|
|
if ( organization == d->mOrganization )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mOrganization = organization;
|
|
}
|
|
|
|
QString Addressee::organization() const
|
|
{
|
|
return d->mOrganization;
|
|
}
|
|
|
|
QString Addressee::organizationLabel()
|
|
{
|
|
return i18n( "Organization" );
|
|
}
|
|
|
|
|
|
void Addressee::setDepartment( const QString &department )
|
|
{
|
|
if ( department == d->mDepartment )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mDepartment = department;
|
|
}
|
|
|
|
QString Addressee::department() const
|
|
{
|
|
return d->mDepartment;
|
|
}
|
|
|
|
QString Addressee::departmentLabel()
|
|
{
|
|
return i18n( "Department" );
|
|
}
|
|
|
|
|
|
void Addressee::setNote( const QString ¬e )
|
|
{
|
|
if ( note == d->mNote )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mNote = note;
|
|
}
|
|
|
|
QString Addressee::note() const
|
|
{
|
|
return d->mNote;
|
|
}
|
|
|
|
QString Addressee::noteLabel()
|
|
{
|
|
return i18n( "Note" );
|
|
}
|
|
|
|
|
|
void Addressee::setProductId( const QString &productId )
|
|
{
|
|
if ( productId == d->mProductId )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mProductId = productId;
|
|
}
|
|
|
|
QString Addressee::productId() const
|
|
{
|
|
return d->mProductId;
|
|
}
|
|
|
|
QString Addressee::productIdLabel()
|
|
{
|
|
return i18n( "Product Identifier" );
|
|
}
|
|
|
|
|
|
void Addressee::setRevision( const QDateTime &revision )
|
|
{
|
|
if ( revision == d->mRevision )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mRevision = revision;
|
|
}
|
|
|
|
QDateTime Addressee::revision() const
|
|
{
|
|
return d->mRevision;
|
|
}
|
|
|
|
QString Addressee::revisionLabel()
|
|
{
|
|
return i18n( "Revision Date" );
|
|
}
|
|
|
|
|
|
void Addressee::setSortString( const QString &sortString )
|
|
{
|
|
if ( sortString == d->mSortString )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mSortString = sortString;
|
|
}
|
|
|
|
QString Addressee::sortString() const
|
|
{
|
|
return d->mSortString;
|
|
}
|
|
|
|
QString Addressee::sortStringLabel()
|
|
{
|
|
return i18n( "Sort String" );
|
|
}
|
|
|
|
|
|
void Addressee::setUrl( const KUrl &url )
|
|
{
|
|
if ( url == d->mUrl )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mUrl = url;
|
|
}
|
|
|
|
KUrl Addressee::url() const
|
|
{
|
|
return d->mUrl;
|
|
}
|
|
|
|
QString Addressee::urlLabel()
|
|
{
|
|
return i18n( "Homepage" );
|
|
}
|
|
|
|
|
|
void Addressee::setSecrecy( const Secrecy &secrecy )
|
|
{
|
|
if ( secrecy == d->mSecrecy )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mSecrecy = secrecy;
|
|
}
|
|
|
|
Secrecy Addressee::secrecy() const
|
|
{
|
|
return d->mSecrecy;
|
|
}
|
|
|
|
QString Addressee::secrecyLabel()
|
|
{
|
|
return i18n( "Security Class" );
|
|
}
|
|
|
|
|
|
void Addressee::setLogo( const Picture &logo )
|
|
{
|
|
if ( logo == d->mLogo )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mLogo = logo;
|
|
}
|
|
|
|
Picture Addressee::logo() const
|
|
{
|
|
return d->mLogo;
|
|
}
|
|
|
|
QString Addressee::logoLabel()
|
|
{
|
|
return i18n( "Logo" );
|
|
}
|
|
|
|
|
|
void Addressee::setPhoto( const Picture &photo )
|
|
{
|
|
if ( photo == d->mPhoto )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mPhoto = photo;
|
|
}
|
|
|
|
Picture Addressee::photo() const
|
|
{
|
|
return d->mPhoto;
|
|
}
|
|
|
|
QString Addressee::photoLabel()
|
|
{
|
|
return i18n( "Photo" );
|
|
}
|
|
|
|
|
|
void Addressee::setSound( const Sound &sound )
|
|
{
|
|
if ( sound == d->mSound )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
d->mSound = sound;
|
|
}
|
|
|
|
Sound Addressee::sound() const
|
|
{
|
|
return d->mSound;
|
|
}
|
|
|
|
QString Addressee::soundLabel()
|
|
{
|
|
return i18n( "Sound" );
|
|
}
|
|
|
|
|
|
void Addressee::setNameFromString( const QString &s )
|
|
{
|
|
QString str = s;
|
|
//remove enclosing quotes from string
|
|
if ( str.length() > 1 &&
|
|
s[ 0 ] == QLatin1Char( '"' ) &&
|
|
s[ s.length() - 1 ] == QLatin1Char( '"' ) ) {
|
|
str = s.mid( 1, s.length() - 2 );
|
|
}
|
|
|
|
setFormattedName( str );
|
|
setName( str );
|
|
|
|
// clear all name parts
|
|
setPrefix( QString() );
|
|
setGivenName( QString() );
|
|
setAdditionalName( QString() );
|
|
setFamilyName( QString() );
|
|
setSuffix( QString() );
|
|
|
|
if ( str.isEmpty() )
|
|
return;
|
|
|
|
static QString spaceStr = QString::fromLatin1( " " );
|
|
static QString emptyStr = QString::fromLatin1( "" );
|
|
AddresseeHelper *helper = AddresseeHelper::self();
|
|
|
|
int i = str.indexOf( QLatin1Char( ',' ) );
|
|
if ( i < 0 ) {
|
|
QStringList parts = str.split( spaceStr );
|
|
int leftOffset = 0;
|
|
int rightOffset = parts.count() - 1;
|
|
|
|
QString suffix;
|
|
while ( rightOffset >= 0 ) {
|
|
if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
|
|
suffix.prepend( parts[ rightOffset ] + ( suffix.isEmpty() ? emptyStr : spaceStr ) );
|
|
rightOffset--;
|
|
} else
|
|
break;
|
|
}
|
|
setSuffix( suffix );
|
|
|
|
if ( rightOffset < 0 )
|
|
return;
|
|
|
|
if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].toLower() ) ) {
|
|
setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
|
|
rightOffset--;
|
|
} else {
|
|
if ( helper->tradeAsFamilyName() )
|
|
setFamilyName( parts[ rightOffset ] );
|
|
else
|
|
setGivenName( parts[ rightOffset ] );
|
|
}
|
|
|
|
QString prefix;
|
|
while ( leftOffset < rightOffset ) {
|
|
if ( helper->containsTitle( parts[ leftOffset ] ) ) {
|
|
prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr ) + parts[ leftOffset ] );
|
|
leftOffset++;
|
|
} else
|
|
break;
|
|
}
|
|
setPrefix( prefix );
|
|
|
|
if ( leftOffset < rightOffset ) {
|
|
setGivenName( parts[ leftOffset ] );
|
|
leftOffset++;
|
|
}
|
|
|
|
QString additionalName;
|
|
while ( leftOffset < rightOffset ) {
|
|
additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr ) + parts[ leftOffset ] );
|
|
leftOffset++;
|
|
}
|
|
setAdditionalName( additionalName );
|
|
} else {
|
|
QString part1 = str.left( i );
|
|
QString part2 = str.mid( i + 1 );
|
|
|
|
QStringList parts = part1.split( spaceStr );
|
|
int leftOffset = 0;
|
|
int rightOffset = parts.count() - 1;
|
|
|
|
if ( parts.count() > 0 ) {
|
|
|
|
QString suffix;
|
|
while ( rightOffset >= 0 ) {
|
|
if ( helper->containsSuffix( parts[ rightOffset ] ) ) {
|
|
suffix.prepend( parts[ rightOffset ] + ( suffix.isEmpty() ? emptyStr : spaceStr ) );
|
|
rightOffset--;
|
|
} else
|
|
break;
|
|
}
|
|
setSuffix( suffix );
|
|
|
|
if ( rightOffset - 1 >= 0 && helper->containsPrefix( parts[ rightOffset - 1 ].toLower() ) ) {
|
|
setFamilyName( parts[ rightOffset - 1 ] + spaceStr + parts[ rightOffset ] );
|
|
rightOffset--;
|
|
} else
|
|
setFamilyName( parts[ rightOffset ] );
|
|
|
|
QString prefix;
|
|
while ( leftOffset < rightOffset ) {
|
|
if ( helper->containsTitle( parts[ leftOffset ] ) ) {
|
|
prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr ) + parts[ leftOffset ] );
|
|
leftOffset++;
|
|
} else
|
|
break;
|
|
}
|
|
} else {
|
|
setPrefix( QString() );
|
|
setFamilyName( QString() );
|
|
setSuffix( QString() );
|
|
}
|
|
|
|
parts = part2.split( spaceStr );
|
|
|
|
leftOffset = 0;
|
|
rightOffset = parts.count();
|
|
|
|
if ( parts.count() > 0 ) {
|
|
|
|
QString prefix;
|
|
while ( leftOffset < rightOffset ) {
|
|
if ( helper->containsTitle( parts[ leftOffset ] ) ) {
|
|
prefix.append( ( prefix.isEmpty() ? emptyStr : spaceStr ) + parts[ leftOffset ] );
|
|
leftOffset++;
|
|
} else
|
|
break;
|
|
}
|
|
setPrefix( prefix );
|
|
|
|
if ( leftOffset < rightOffset ) {
|
|
setGivenName( parts[ leftOffset ] );
|
|
leftOffset++;
|
|
}
|
|
|
|
QString additionalName;
|
|
while ( leftOffset < rightOffset ) {
|
|
additionalName.append( ( additionalName.isEmpty() ? emptyStr : spaceStr ) + parts[ leftOffset ] );
|
|
leftOffset++;
|
|
}
|
|
setAdditionalName( additionalName );
|
|
} else {
|
|
setGivenName( QString() );
|
|
setAdditionalName( QString() );
|
|
}
|
|
}
|
|
}
|
|
|
|
QString Addressee::realName() const
|
|
{
|
|
QString n( formattedName() );
|
|
if ( !n.isEmpty() )
|
|
return n;
|
|
|
|
n = assembledName();
|
|
if ( !n.isEmpty() )
|
|
return n;
|
|
|
|
n = name();
|
|
if ( !n.isEmpty() )
|
|
return n;
|
|
|
|
return organization();
|
|
}
|
|
|
|
QString Addressee::assembledName() const
|
|
{
|
|
const QString name = prefix() + QLatin1Char( ' ' ) +
|
|
givenName() + QLatin1Char( ' ' ) +
|
|
additionalName() + QLatin1Char( ' ' ) +
|
|
familyName() + QLatin1Char( ' ' ) +
|
|
suffix();
|
|
|
|
return name.simplified();
|
|
}
|
|
|
|
QString Addressee::fullEmail( const QString &email ) const
|
|
{
|
|
QString e;
|
|
if ( email.isNull() ) {
|
|
e = preferredEmail();
|
|
} else {
|
|
e = email;
|
|
}
|
|
if ( e.isEmpty() ) return QString();
|
|
|
|
QString text;
|
|
if ( realName().isEmpty() )
|
|
text = e;
|
|
else {
|
|
QRegExp needQuotes( QLatin1String( "[^ 0-9A-Za-z\\x0080-\\xFFFF]" ) );
|
|
if ( realName().indexOf( needQuotes ) != -1 ) {
|
|
QString name = realName();
|
|
name.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
|
|
text = QLatin1String( "\"" ) + name + QLatin1String( "\" <" ) + e + QLatin1Char( '>' );
|
|
} else
|
|
text = realName() + QLatin1String( " <" ) + e + QLatin1Char( '>' );
|
|
}
|
|
|
|
return text;
|
|
}
|
|
|
|
void Addressee::insertEmail( const QString &email, bool preferred )
|
|
{
|
|
if ( email.simplified().isEmpty() )
|
|
return;
|
|
|
|
if ( d->mEmails.contains( email ) ) {
|
|
if ( !preferred || d->mEmails.first() == email )
|
|
return;
|
|
|
|
d->mEmails.removeAll( email );
|
|
d->mEmails.prepend( email );
|
|
} else {
|
|
d->mEmpty = false;
|
|
if ( preferred ) {
|
|
d->mEmails.prepend( email );
|
|
} else {
|
|
d->mEmails.append( email );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Addressee::removeEmail( const QString &email )
|
|
{
|
|
if ( d->mEmails.contains( email ) ) {
|
|
d->mEmails.removeAll( email );
|
|
}
|
|
}
|
|
|
|
QString Addressee::preferredEmail() const
|
|
{
|
|
if ( d->mEmails.count() == 0 )
|
|
return QString();
|
|
else
|
|
return d->mEmails.first();
|
|
}
|
|
|
|
QStringList Addressee::emails() const
|
|
{
|
|
return d->mEmails;
|
|
}
|
|
|
|
void Addressee::setEmails( const QStringList& emails )
|
|
{
|
|
d->mEmails = emails;
|
|
}
|
|
void Addressee::insertPhoneNumber( const PhoneNumber &phoneNumber )
|
|
{
|
|
d->mEmpty = false;
|
|
|
|
PhoneNumber::List::Iterator it;
|
|
for ( it = d->mPhoneNumbers.begin(); it != d->mPhoneNumbers.end(); ++it ) {
|
|
if ( ( *it ).id() == phoneNumber.id() ) {
|
|
*it = phoneNumber;
|
|
return;
|
|
}
|
|
}
|
|
if ( !phoneNumber.number().simplified().isEmpty() )
|
|
d->mPhoneNumbers.append( phoneNumber );
|
|
}
|
|
|
|
void Addressee::removePhoneNumber( const PhoneNumber &phoneNumber )
|
|
{
|
|
PhoneNumber::List::Iterator it;
|
|
for ( it = d->mPhoneNumbers.begin(); it != d->mPhoneNumbers.end(); ++it ) {
|
|
if ( ( *it ).id() == phoneNumber.id() ) {
|
|
d->mPhoneNumbers.erase( it );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
PhoneNumber Addressee::phoneNumber( PhoneNumber::Type type ) const
|
|
{
|
|
PhoneNumber phoneNumber( QString(), type );
|
|
PhoneNumber::List::ConstIterator it;
|
|
for ( it = d->mPhoneNumbers.constBegin(); it != d->mPhoneNumbers.constEnd(); ++it ) {
|
|
if ( matchBinaryPattern( ( *it ).type(), type ) ) {
|
|
if ( ( *it ).type() & PhoneNumber::Pref ) {
|
|
return ( *it );
|
|
} else if ( phoneNumber.number().isEmpty() ) {
|
|
phoneNumber = ( *it );
|
|
}
|
|
}
|
|
}
|
|
|
|
return phoneNumber;
|
|
}
|
|
|
|
PhoneNumber::List Addressee::phoneNumbers() const
|
|
{
|
|
return d->mPhoneNumbers;
|
|
}
|
|
|
|
PhoneNumber::List Addressee::phoneNumbers( PhoneNumber::Type type ) const
|
|
{
|
|
PhoneNumber::List list;
|
|
|
|
PhoneNumber::List::ConstIterator it;
|
|
PhoneNumber::List::ConstIterator end( d->mPhoneNumbers.constEnd() );
|
|
for ( it = d->mPhoneNumbers.constBegin(); it != end; ++it ) {
|
|
if ( matchBinaryPattern( ( *it ).type(), type ) ) {
|
|
list.append( *it );
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
PhoneNumber Addressee::findPhoneNumber( const QString &id ) const
|
|
{
|
|
PhoneNumber::List::ConstIterator it;
|
|
PhoneNumber::List::ConstIterator end( d->mPhoneNumbers.constEnd() );
|
|
for ( it = d->mPhoneNumbers.constBegin(); it != end; ++it ) {
|
|
if ( ( *it ).id() == id ) {
|
|
return *it;
|
|
}
|
|
}
|
|
return PhoneNumber();
|
|
}
|
|
|
|
void Addressee::insertKey( const Key &key )
|
|
{
|
|
d->mEmpty = false;
|
|
|
|
Key::List::Iterator it;
|
|
for ( it = d->mKeys.begin(); it != d->mKeys.end(); ++it ) {
|
|
if ( ( *it ).id() == key.id() ) {
|
|
*it = key;
|
|
return;
|
|
}
|
|
}
|
|
d->mKeys.append( key );
|
|
}
|
|
|
|
void Addressee::removeKey( const Key &key )
|
|
{
|
|
Key::List::Iterator it;
|
|
for ( it = d->mKeys.begin(); it != d->mKeys.end(); ++it ) {
|
|
if ( ( *it ).id() == key.id() ) {
|
|
d->mKeys.removeAll( key );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Key Addressee::key( Key::Type type, QString customTypeString ) const
|
|
{
|
|
Key::List::ConstIterator it;
|
|
Key::List::ConstIterator end( d->mKeys.constEnd() );
|
|
for ( it = d->mKeys.constBegin(); it != end; ++it ) {
|
|
if ( ( *it ).type() == type ) {
|
|
if ( type == Key::Custom ) {
|
|
if ( customTypeString.isEmpty() ) {
|
|
return *it;
|
|
} else {
|
|
if ( ( *it ).customTypeString() == customTypeString )
|
|
return ( *it );
|
|
}
|
|
} else {
|
|
return *it;
|
|
}
|
|
}
|
|
}
|
|
return Key( QString(), type );
|
|
}
|
|
|
|
void Addressee::setKeys( const Key::List& list )
|
|
{
|
|
d->mKeys = list;
|
|
}
|
|
|
|
Key::List Addressee::keys() const
|
|
{
|
|
return d->mKeys;
|
|
}
|
|
|
|
Key::List Addressee::keys( Key::Type type, QString customTypeString ) const
|
|
{
|
|
Key::List list;
|
|
|
|
Key::List::ConstIterator it;
|
|
Key::List::ConstIterator end( d->mKeys.constEnd() );
|
|
for ( it = d->mKeys.constBegin(); it != end; ++it ) {
|
|
if ( ( *it ).type() == type ) {
|
|
if ( type == Key::Custom ) {
|
|
if ( customTypeString.isEmpty() ) {
|
|
list.append( *it );
|
|
} else {
|
|
if ( ( *it ).customTypeString() == customTypeString )
|
|
list.append( *it );
|
|
}
|
|
} else {
|
|
list.append( *it );
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
Key Addressee::findKey( const QString &id ) const
|
|
{
|
|
Key::List::ConstIterator it;
|
|
Key::List::ConstIterator end( d->mKeys.constEnd() );
|
|
for ( it = d->mKeys.constBegin(); it != end; ++it ) {
|
|
if ( ( *it ).id() == id ) {
|
|
return *it;
|
|
}
|
|
}
|
|
return Key();
|
|
}
|
|
|
|
QString Addressee::toString() const
|
|
{
|
|
QString str;
|
|
|
|
str += QLatin1String( "Addressee {\n" );
|
|
str += QString::fromLatin1( " Uid: %1\n" ).arg( uid() );
|
|
|
|
str += QString::fromLatin1( " Name: %1\n" ).arg( name() );
|
|
str += QString::fromLatin1( " FormattedName: %1\n" ).arg( formattedName() );
|
|
str += QString::fromLatin1( " FamilyName: %1\n" ).arg( familyName() );
|
|
str += QString::fromLatin1( " GivenName: %1\n" ).arg( givenName() );
|
|
str += QString::fromLatin1( " AdditionalName: %1\n" ).arg( additionalName() );
|
|
str += QString::fromLatin1( " Prefix: %1\n" ).arg( prefix() );
|
|
str += QString::fromLatin1( " Suffix: %1\n" ).arg( suffix() );
|
|
str += QString::fromLatin1( " NickName: %1\n" ).arg( nickName() );
|
|
str += QString::fromLatin1( " Birthday: %1\n" ).arg( birthday().toString() );
|
|
str += QString::fromLatin1( " Mailer: %1\n" ).arg( mailer() );
|
|
str += QString::fromLatin1( " TimeZone: %1\n" ).arg( timeZone().toString() );
|
|
str += QString::fromLatin1( " Geo: %1\n" ).arg( geo().toString() );
|
|
str += QString::fromLatin1( " Title: %1\n" ).arg( title() );
|
|
str += QString::fromLatin1( " Role: %1\n" ).arg( role() );
|
|
str += QString::fromLatin1( " Organization: %1\n" ).arg( organization() );
|
|
str += QString::fromLatin1( " Department: %1\n" ).arg( department() );
|
|
str += QString::fromLatin1( " Note: %1\n" ).arg( note() );
|
|
str += QString::fromLatin1( " ProductId: %1\n" ).arg( productId() );
|
|
str += QString::fromLatin1( " Revision: %1\n" ).arg( revision().toString() );
|
|
str += QString::fromLatin1( " SortString: %1\n" ).arg( sortString() );
|
|
str += QString::fromLatin1( " Url: %1\n" ).arg( url().url() );
|
|
str += QString::fromLatin1( " Secrecy: %1\n" ).arg( secrecy().toString() );
|
|
str += QString::fromLatin1( " Logo: %1\n" ).arg( logo().toString() );
|
|
str += QString::fromLatin1( " Photo: %1\n" ).arg( photo().toString() );
|
|
str += QString::fromLatin1( " Sound: %1\n" ).arg( sound().toString() );
|
|
|
|
str += QLatin1String( " Emails {\n" );
|
|
const QStringList e = emails();
|
|
QStringList::ConstIterator it;
|
|
for ( it = e.begin(); it != e.end(); ++it ) {
|
|
str += QString::fromLatin1( " %1\n" ).arg( *it );
|
|
}
|
|
str += QLatin1String( " }\n" );
|
|
|
|
str += QLatin1String( " PhoneNumbers {\n" );
|
|
const PhoneNumber::List p = phoneNumbers();
|
|
PhoneNumber::List::ConstIterator it2;
|
|
for ( it2 = p.begin(); it2 != p.end(); ++it2 ) {
|
|
str += ( *it2 ).toString();
|
|
}
|
|
str += QLatin1String( " }\n" );
|
|
|
|
str += QLatin1String( " Addresses {\n" );
|
|
const Address::List a = addresses();
|
|
Address::List::ConstIterator it3;
|
|
for ( it3 = a.begin(); it3 != a.end(); ++it3 ) {
|
|
str += ( *it3 ).toString();
|
|
}
|
|
str += QLatin1String( " }\n" );
|
|
|
|
str += QLatin1String( " Keys {\n" );
|
|
const Key::List k = keys();
|
|
Key::List::ConstIterator it4;
|
|
for ( it4 = k.begin(); it4 != k.end(); ++it4 ) {
|
|
str += ( *it4 ).toString();
|
|
}
|
|
str += QLatin1String( " }\n" );
|
|
|
|
str += QLatin1String( "}\n" );
|
|
|
|
return str;
|
|
}
|
|
|
|
|
|
void Addressee::insertAddress( const Address &address )
|
|
{
|
|
if ( address.isEmpty() )
|
|
return;
|
|
|
|
d->mEmpty = false;
|
|
|
|
Address::List::Iterator it;
|
|
for ( it = d->mAddresses.begin(); it != d->mAddresses.end(); ++it ) {
|
|
if ( ( *it ).id() == address.id() ) {
|
|
*it = address;
|
|
return;
|
|
}
|
|
}
|
|
|
|
d->mAddresses.append( address );
|
|
}
|
|
|
|
void Addressee::removeAddress( const Address &address )
|
|
{
|
|
Address::List::Iterator it;
|
|
for ( it = d->mAddresses.begin(); it != d->mAddresses.end(); ++it ) {
|
|
if ( ( *it ).id() == address.id() ) {
|
|
d->mAddresses.erase( it );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Address Addressee::address( Address::Type type ) const
|
|
{
|
|
Address address( type );
|
|
Address::List::ConstIterator it;
|
|
Address::List::ConstIterator end( d->mAddresses.constEnd() );
|
|
for ( it = d->mAddresses.constBegin(); it != end; ++it ) {
|
|
if ( matchBinaryPattern( ( *it ).type(), type ) ) {
|
|
if ( ( *it ).type() & Address::Pref ) {
|
|
return ( *it );
|
|
} else if ( address.isEmpty() ) {
|
|
address = ( *it );
|
|
}
|
|
}
|
|
}
|
|
|
|
return address;
|
|
}
|
|
|
|
Address::List Addressee::addresses() const
|
|
{
|
|
return d->mAddresses;
|
|
}
|
|
|
|
Address::List Addressee::addresses( Address::Type type ) const
|
|
{
|
|
Address::List list;
|
|
|
|
Address::List::ConstIterator it;
|
|
Address::List::ConstIterator end( d->mAddresses.constEnd() );
|
|
for ( it = d->mAddresses.constBegin(); it != end; ++it ) {
|
|
if ( matchBinaryPattern( ( *it ).type(), type ) ) {
|
|
list.append( *it );
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
Address Addressee::findAddress( const QString &id ) const
|
|
{
|
|
Address::List::ConstIterator it;
|
|
Address::List::ConstIterator end( d->mAddresses.constEnd() );
|
|
for ( it = d->mAddresses.constBegin(); it != end; ++it ) {
|
|
if ( ( *it ).id() == id ) {
|
|
return *it;
|
|
}
|
|
}
|
|
return Address();
|
|
}
|
|
|
|
void Addressee::insertCategory( const QString &c )
|
|
{
|
|
d->mEmpty = false;
|
|
|
|
if ( d->mCategories.contains( c ) )
|
|
return;
|
|
|
|
d->mCategories.append( c );
|
|
}
|
|
|
|
void Addressee::removeCategory( const QString &category )
|
|
{
|
|
if ( d->mCategories.contains( category ) ) {
|
|
d->mCategories.removeAll( category );
|
|
}
|
|
}
|
|
|
|
bool Addressee::hasCategory( const QString &category ) const
|
|
{
|
|
return d->mCategories.contains( category );
|
|
}
|
|
|
|
void Addressee::setCategories( const QStringList &c )
|
|
{
|
|
d->mEmpty = false;
|
|
|
|
d->mCategories = c;
|
|
}
|
|
|
|
QStringList Addressee::categories() const
|
|
{
|
|
return d->mCategories;
|
|
}
|
|
|
|
void Addressee::insertCustom( const QString &app, const QString &name,
|
|
const QString &value )
|
|
{
|
|
if ( value.isEmpty() || name.isEmpty() || app.isEmpty() ) {
|
|
return;
|
|
}
|
|
|
|
d->mEmpty = false;
|
|
|
|
const QString qualifiedName = app + QLatin1Char( '-' ) + name;
|
|
|
|
d->mCustomFields.insert( qualifiedName, value );
|
|
}
|
|
|
|
void Addressee::removeCustom( const QString &app, const QString &name )
|
|
{
|
|
const QString qualifiedName = app + QLatin1Char( '-' ) + name;
|
|
|
|
d->mCustomFields.remove( qualifiedName );
|
|
}
|
|
|
|
QString Addressee::custom( const QString &app, const QString &name ) const
|
|
{
|
|
const QString qualifiedName = app + QLatin1Char( '-' ) + name;
|
|
|
|
return d->mCustomFields.value( qualifiedName );
|
|
}
|
|
|
|
void Addressee::setCustoms( const QStringList &customs )
|
|
{
|
|
d->mEmpty = false;
|
|
|
|
d->mCustomFields.clear();
|
|
|
|
foreach ( const QString &custom, customs ) {
|
|
const int index = custom.indexOf( QLatin1Char( ':' ) );
|
|
if ( index == -1 )
|
|
continue;
|
|
|
|
const QString qualifiedName = custom.left( index );
|
|
const QString value = custom.mid( index + 1 );
|
|
|
|
d->mCustomFields.insert( qualifiedName, value );
|
|
}
|
|
}
|
|
|
|
QStringList Addressee::customs() const
|
|
{
|
|
QStringList result;
|
|
|
|
QMapIterator<QString, QString> it( d->mCustomFields );
|
|
while ( it.hasNext() ) {
|
|
it.next();
|
|
result << it.key() + QLatin1Char( ':' ) + it.value();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void Addressee::parseEmailAddress( const QString &rawEmail, QString &fullName,
|
|
QString &email )
|
|
{
|
|
// This is a simplified version of KPIM::splitAddress().
|
|
|
|
fullName.clear();
|
|
email.clear();
|
|
if ( rawEmail.isEmpty() )
|
|
return; // KPIM::AddressEmpty;
|
|
|
|
// The code works on 8-bit strings, so convert the input to UTF-8.
|
|
QByteArray address = rawEmail.toUtf8();
|
|
|
|
QByteArray displayName;
|
|
QByteArray addrSpec;
|
|
QByteArray comment;
|
|
|
|
// The following is a primitive parser for a mailbox-list (cf. RFC 2822).
|
|
// The purpose is to extract a displayable string from the mailboxes.
|
|
// Comments in the addr-spec are not handled. No error checking is done.
|
|
|
|
enum { TopLevel, InComment, InAngleAddress } context = TopLevel;
|
|
bool inQuotedString = false;
|
|
int commentLevel = 0;
|
|
bool stop = false;
|
|
|
|
for ( char* p = address.data(); *p && !stop; ++p ) {
|
|
switch ( context ) {
|
|
case TopLevel : {
|
|
switch ( *p ) {
|
|
case '"' : inQuotedString = !inQuotedString;
|
|
displayName += *p;
|
|
break;
|
|
case '(' : if ( !inQuotedString ) {
|
|
context = InComment;
|
|
commentLevel = 1;
|
|
}
|
|
else
|
|
displayName += *p;
|
|
break;
|
|
case '<' : if ( !inQuotedString ) {
|
|
context = InAngleAddress;
|
|
}
|
|
else
|
|
displayName += *p;
|
|
break;
|
|
case '\\' : // quoted character
|
|
displayName += *p;
|
|
++p; // skip the '\'
|
|
if ( *p )
|
|
displayName += *p;
|
|
else
|
|
//return KPIM::UnexpectedEnd;
|
|
goto ABORT_PARSING;
|
|
break;
|
|
case ',' : if ( !inQuotedString ) {
|
|
//if ( allowMultipleAddresses )
|
|
// stop = true;
|
|
//else
|
|
// return KPIM::UnexpectedComma;
|
|
goto ABORT_PARSING;
|
|
}
|
|
else
|
|
displayName += *p;
|
|
break;
|
|
default : displayName += *p;
|
|
}
|
|
break;
|
|
}
|
|
case InComment : {
|
|
switch ( *p ) {
|
|
case '(' : ++commentLevel;
|
|
comment += *p;
|
|
break;
|
|
case ')' : --commentLevel;
|
|
if ( commentLevel == 0 ) {
|
|
context = TopLevel;
|
|
comment += ' '; // separate the text of several comments
|
|
}
|
|
else
|
|
comment += *p;
|
|
break;
|
|
case '\\' : // quoted character
|
|
comment += *p;
|
|
++p; // skip the '\'
|
|
if ( *p )
|
|
comment += *p;
|
|
else
|
|
//return KPIM::UnexpectedEnd;
|
|
goto ABORT_PARSING;
|
|
break;
|
|
default : comment += *p;
|
|
}
|
|
break;
|
|
}
|
|
case InAngleAddress : {
|
|
switch ( *p ) {
|
|
case '"' : inQuotedString = !inQuotedString;
|
|
addrSpec += *p;
|
|
break;
|
|
case '>' : if ( !inQuotedString ) {
|
|
context = TopLevel;
|
|
}
|
|
else
|
|
addrSpec += *p;
|
|
break;
|
|
case '\\' : // quoted character
|
|
addrSpec += *p;
|
|
++p; // skip the '\'
|
|
if ( *p )
|
|
addrSpec += *p;
|
|
else
|
|
//return KPIM::UnexpectedEnd;
|
|
goto ABORT_PARSING;
|
|
break;
|
|
default : addrSpec += *p;
|
|
}
|
|
break;
|
|
}
|
|
} // switch ( context )
|
|
}
|
|
|
|
ABORT_PARSING:
|
|
displayName = displayName.trimmed();
|
|
comment = comment.trimmed();
|
|
addrSpec = addrSpec.trimmed();
|
|
|
|
fullName = QString::fromUtf8( displayName );
|
|
email = QString::fromUtf8( addrSpec );
|
|
|
|
// check for errors
|
|
if ( inQuotedString )
|
|
return; // KPIM::UnbalancedQuote;
|
|
if ( context == InComment )
|
|
return; // KPIM::UnbalancedParens;
|
|
if ( context == InAngleAddress )
|
|
return; // KPIM::UnclosedAngleAddr;
|
|
|
|
if ( addrSpec.isEmpty() ) {
|
|
if ( displayName.isEmpty() )
|
|
return; // KPIM::NoAddressSpec;
|
|
else {
|
|
//addrSpec = displayName;
|
|
//displayName.truncate( 0 );
|
|
// Address of the form "foo@bar" or "foo@bar (Name)".
|
|
email = fullName;
|
|
fullName = QString::fromUtf8( comment );
|
|
}
|
|
}
|
|
|
|
email = email.toLower();
|
|
// Check that we do not have any extra characters on the end of the
|
|
// strings
|
|
unsigned int len = fullName.length();
|
|
if ( fullName[ 0 ] == QLatin1Char( '"' ) && fullName[ len - 1 ] == QLatin1Char( '"' ) ) {
|
|
fullName = fullName.mid( 1, len - 2 );
|
|
}
|
|
}
|
|
|
|
#ifndef KDEPIM_NO_KRESOURCES
|
|
void Addressee::setResource( Resource *resource )
|
|
{
|
|
d->mResource = resource;
|
|
}
|
|
|
|
Resource *Addressee::resource() const
|
|
{
|
|
return d->mResource;
|
|
}
|
|
#endif
|
|
|
|
void Addressee::setChanged( bool value )
|
|
{
|
|
d->mChanged = value;
|
|
}
|
|
|
|
bool Addressee::changed() const
|
|
{
|
|
return d->mChanged;
|
|
}
|
|
|
|
void Addressee::setSortMode( KABC::SortMode *mode )
|
|
{
|
|
Private::mSortMode = mode;
|
|
}
|
|
|
|
bool Addressee::operator< ( const Addressee &addr ) const
|
|
{
|
|
if ( !Private::mSortMode )
|
|
return false;
|
|
else
|
|
return Private::mSortMode->lesser( *this, addr );
|
|
}
|
|
|
|
QString Addressee::mimeType()
|
|
{
|
|
return QLatin1String( "text/directory" );
|
|
}
|
|
|
|
QDataStream &KABC::operator<<( QDataStream &s, const Addressee &a )
|
|
{
|
|
s << a.d->mUid;
|
|
|
|
s << a.d->mName;
|
|
s << a.d->mFormattedName;
|
|
s << a.d->mFamilyName;
|
|
s << a.d->mGivenName;
|
|
s << a.d->mAdditionalName;
|
|
s << a.d->mPrefix;
|
|
s << a.d->mSuffix;
|
|
s << a.d->mNickName;
|
|
s << a.d->mBirthday;
|
|
s << a.d->mMailer;
|
|
s << a.d->mTimeZone;
|
|
s << a.d->mGeo;
|
|
s << a.d->mTitle;
|
|
s << a.d->mRole;
|
|
s << a.d->mOrganization;
|
|
s << a.d->mDepartment;
|
|
s << a.d->mNote;
|
|
s << a.d->mProductId;
|
|
s << a.d->mRevision;
|
|
s << a.d->mSortString;
|
|
s << a.d->mUrl;
|
|
s << a.d->mSecrecy;
|
|
s << a.d->mLogo;
|
|
s << a.d->mPhoto;
|
|
s << a.d->mSound;
|
|
s << a.d->mPhoneNumbers;
|
|
s << a.d->mAddresses;
|
|
s << a.d->mEmails;
|
|
s << a.d->mCategories;
|
|
s << a.customs();
|
|
s << a.d->mKeys;
|
|
return s;
|
|
}
|
|
|
|
QDataStream &KABC::operator>>( QDataStream &s, Addressee &a )
|
|
{
|
|
s >> a.d->mUid;
|
|
|
|
s >> a.d->mName;
|
|
s >> a.d->mFormattedName;
|
|
s >> a.d->mFamilyName;
|
|
s >> a.d->mGivenName;
|
|
s >> a.d->mAdditionalName;
|
|
s >> a.d->mPrefix;
|
|
s >> a.d->mSuffix;
|
|
s >> a.d->mNickName;
|
|
s >> a.d->mBirthday;
|
|
s >> a.d->mMailer;
|
|
s >> a.d->mTimeZone;
|
|
s >> a.d->mGeo;
|
|
s >> a.d->mTitle;
|
|
s >> a.d->mRole;
|
|
s >> a.d->mOrganization;
|
|
s >> a.d->mDepartment;
|
|
s >> a.d->mNote;
|
|
s >> a.d->mProductId;
|
|
s >> a.d->mRevision;
|
|
s >> a.d->mSortString;
|
|
s >> a.d->mUrl;
|
|
s >> a.d->mSecrecy;
|
|
s >> a.d->mLogo;
|
|
s >> a.d->mPhoto;
|
|
s >> a.d->mSound;
|
|
s >> a.d->mPhoneNumbers;
|
|
s >> a.d->mAddresses;
|
|
s >> a.d->mEmails;
|
|
s >> a.d->mCategories;
|
|
QStringList customFields;
|
|
s >> customFields;
|
|
a.setCustoms( customFields );
|
|
s >> a.d->mKeys;
|
|
|
|
a.d->mEmpty = false;
|
|
|
|
return s;
|
|
}
|
|
|
|
bool matchBinaryPattern( int value, int pattern )
|
|
{
|
|
/**
|
|
We want to match all telephonnumbers/addresses which have the bits in the
|
|
pattern set. More are allowed.
|
|
if pattern == 0 we have a special handling, then we want only those with
|
|
exactly no bit set.
|
|
*/
|
|
if ( pattern == 0 )
|
|
return ( value == 0 );
|
|
else
|
|
return ( pattern == ( pattern & value ) );
|
|
}
|
|
|
|
template <class L>
|
|
bool listEquals( const QList<L> &list, const QList<L> &pattern )
|
|
{
|
|
if ( list.count() != pattern.count() )
|
|
return false;
|
|
const int numberOfElement( list.count() );
|
|
for ( int i = 0; i < numberOfElement; ++i ) {
|
|
if ( !pattern.contains( list[ i ] ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool listEquals( const QStringList &list, const QStringList &pattern )
|
|
{
|
|
if ( list.count() != pattern.count() )
|
|
return false;
|
|
|
|
const int numberOfElement( list.count() );
|
|
for ( int i = 0; i < numberOfElement; ++i ) {
|
|
if ( !pattern.contains( list[ i ] ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool emailsEquals( const QStringList &list, const QStringList &pattern )
|
|
{
|
|
if ( list.count() != pattern.count() )
|
|
return false;
|
|
|
|
if ( list.isEmpty() )
|
|
return true;
|
|
|
|
if ( list.first() != pattern.first() )
|
|
return false;
|
|
|
|
QStringList::ConstIterator it;
|
|
QStringList::ConstIterator end( list.constEnd() );
|
|
for ( it = list.constBegin(); it != end; ++it ) {
|
|
if ( !pattern.contains( *it ) ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|