11#include <QRegularExpression>
15#include "kcontacts_debug.h"
16#include <KLocalizedString>
19#include "addresseehelper_p.h"
20#include "parametermap_p.h"
22using namespace KContacts;
24static bool matchBinaryPattern(
int value,
int pattern);
35inline bool operator==(
const CustomData &a,
const CustomData &b)
37 return std::tie(a.name, a.value) == std::tie(b.name, b.value);
40inline bool operator!=(
const CustomData &a,
const CustomData &b)
42 return std::tie(a.name, a.value) != std::tie(b.name, b.value);
45inline bool operator<(
const CustomData &a,
const CustomData &b)
47 return a.name < b.name;
54 : mUid(QUuid::createUuid().
toString().mid(1, 36))
57 , mBirthdayWithTime(false)
62 Private(
const Private &other)
67 mFormattedName = other.mFormattedName;
68 mFamilyName = other.mFamilyName;
69 mGivenName = other.mGivenName;
70 mAdditionalName = other.mAdditionalName;
71 mPrefix = other.mPrefix;
72 mSuffix = other.mSuffix;
73 mBirthday = other.mBirthday;
74 mBirthdayWithTime = other.mBirthdayWithTime;
75 mMailer = other.mMailer;
76 mTimeZone = other.mTimeZone;
78 mDepartment = other.mDepartment;
80 mProductId = other.mProductId;
81 mRevision = other.mRevision;
82 mSortString = other.mSortString;
83 mSecrecy = other.mSecrecy;
85 mPhoto = other.mPhoto;
86 mSound = other.mSound;
88 mPhoneNumbers = other.mPhoneNumbers;
89 mAddresses = other.mAddresses;
91 mLangs = other.mLangs;
92 mGender = other.mGender;
93 mEmails = other.mEmails;
94 mCategories = other.mCategories;
95 mCustomFields = other.mCustomFields;
96 mCalendarUrl = other.mCalendarUrl;
97 mSoundListExtra = other.mSoundListExtra;
98 mPhotoExtraList = other.mPhotoExtraList;
99 mLogoExtraList = other.mLogoExtraList;
100 mUrlExtraList = other.mUrlExtraList;
101 mMembers = other.mMembers;
102 mRelationships = other.mRelationships;
103 mSources = other.mSources;
104 mEmpty = other.mEmpty;
105 mImpps = other.mImpps;
106 mChanged = other.mChanged;
107 mTitleExtraList = other.mTitleExtraList;
108 mRoleExtraList = other.mRoleExtraList;
109 mOrgExtraList = other.mOrgExtraList;
116 std::vector<CustomData>::iterator
findByName(
const QString &qualifiedName)
118 return std::find_if(mCustomFields.begin(), mCustomFields.end(), [&qualifiedName](
const CustomData &info) {
119 return info.name == qualifiedName;
123 std::vector<CustomData>::const_iterator
findByName(
const QString &qualifiedName)
const
125 return std::find_if(mCustomFields.cbegin(), mCustomFields.cend(), [&qualifiedName](
const CustomData &info) {
126 return info.name == qualifiedName;
132 QString mFormattedName;
135 QString mAdditionalName;
160 QStringList mCategories;
161 std::vector<CustomData> mCustomFields;
162 CalendarUrl::List mCalendarUrl;
163 Sound::List mSoundListExtra;
164 Picture::List mPhotoExtraList;
165 Picture::List mLogoExtraList;
166 ResourceLocatorUrl::List mUrlExtraList;
167 QList<QUrl> mSources;
168 QStringList mMembers;
169 Related::List mRelationships;
170 FieldGroup::List mFieldGroupList;
171 Title::List mTitleExtraList;
172 Role::List mRoleExtraList;
173 Org::List mOrgExtraList;
174 NickName::List mNickNameExtraList;
175 ClientPidMap::List mClientPidMapList;
178 bool mBirthdayWithTime;
197 if (
this != &other) {
206 if (d->mUid != addressee.d->mUid) {
207 qCDebug(KCONTACTS_LOG) <<
"uid differs";
211 if (d->mName != addressee.d->mName
212 && !(d->mName.isEmpty() && addressee.d->mName.isEmpty())) {
213 qCDebug(KCONTACTS_LOG) <<
"name differs";
217 if (d->mFormattedName != addressee.d->mFormattedName
218 && !(d->mFormattedName.isEmpty() && addressee.d->mFormattedName.isEmpty())) {
219 qCDebug(KCONTACTS_LOG) <<
"formattedName differs";
223 if (d->mFamilyName != addressee.d->mFamilyName
224 && !(d->mFamilyName.isEmpty() && addressee.d->mFamilyName.isEmpty())) {
225 qCDebug(KCONTACTS_LOG) <<
"familyName differs";
229 if (d->mGivenName != addressee.d->mGivenName
230 && !(d->mGivenName.isEmpty() && addressee.d->mGivenName.isEmpty())) {
231 qCDebug(KCONTACTS_LOG) <<
"givenName differs";
235 if (d->mAdditionalName != addressee.d->mAdditionalName
236 && !(d->mAdditionalName.isEmpty() && addressee.d->mAdditionalName.isEmpty())) {
237 qCDebug(KCONTACTS_LOG) <<
"additionalName differs";
241 if (d->mPrefix != addressee.d->mPrefix
242 && !(d->mPrefix.isEmpty() && addressee.d->mPrefix.isEmpty())) {
243 qCDebug(KCONTACTS_LOG) <<
"prefix differs";
247 if (d->mSuffix != addressee.d->mSuffix
248 && !(d->mSuffix.isEmpty() && addressee.d->mSuffix.isEmpty())) {
249 qCDebug(KCONTACTS_LOG) <<
"suffix differs";
253 if (d->mBirthday != addressee.d->mBirthday
254 || d->mBirthdayWithTime != addressee.d->mBirthdayWithTime) {
255 qCDebug(KCONTACTS_LOG) <<
"birthday differs";
259 if (d->mMailer != addressee.d->mMailer
260 && !(d->mMailer.isEmpty() && addressee.d->mMailer.isEmpty())) {
261 qCDebug(KCONTACTS_LOG) <<
"mailer differs";
265 if (d->mTimeZone != addressee.d->mTimeZone) {
266 qCDebug(KCONTACTS_LOG) <<
"timeZone differs";
270 if (d->mGeo != addressee.d->mGeo) {
271 qCDebug(KCONTACTS_LOG) <<
"geo differs";
275 if (d->mDepartment != addressee.d->mDepartment
276 && !(d->mDepartment.isEmpty() && addressee.d->mDepartment.isEmpty())) {
277 qCDebug(KCONTACTS_LOG) <<
"department differs";
281 if (d->mNote != addressee.d->mNote
282 && !(d->mNote.isEmpty() && addressee.d->mNote.isEmpty())) {
283 qCDebug(KCONTACTS_LOG) <<
"note differs";
287 if (d->mProductId != addressee.d->mProductId
288 && !(d->mProductId.isEmpty() && addressee.d->mProductId.isEmpty())) {
289 qCDebug(KCONTACTS_LOG) <<
"productId differs";
293 if (d->mSortString != addressee.d->mSortString
294 && !(d->mSortString.isEmpty() && addressee.d->mSortString.isEmpty())) {
295 qCDebug(KCONTACTS_LOG) <<
"sortString differs";
299 if (d->mSecrecy != addressee.d->mSecrecy) {
300 qCDebug(KCONTACTS_LOG) <<
"secrecy differs";
304 if (d->mLogo != addressee.d->mLogo) {
305 qCDebug(KCONTACTS_LOG) <<
"logo differs";
309 if (d->mPhoto != addressee.d->mPhoto) {
310 qCDebug(KCONTACTS_LOG) <<
"photo differs";
314 if (d->mSound != addressee.d->mSound) {
315 qCDebug(KCONTACTS_LOG) <<
"sound differs";
319 if (!listEquals(d->mPhoneNumbers, addressee.d->mPhoneNumbers)) {
320 qCDebug(KCONTACTS_LOG) <<
"phoneNumbers differs";
324 if (!listEquals(d->mAddresses, addressee.d->mAddresses)) {
325 qCDebug(KCONTACTS_LOG) <<
"addresses differs";
329 if (!listEquals(d->mKeys, addressee.d->mKeys)) {
330 qCDebug(KCONTACTS_LOG) <<
"keys differs";
333 if (!listEquals(d->mEmails, addressee.d->mEmails)) {
334 qCDebug(KCONTACTS_LOG) <<
"emails differs";
338 if (!listEquals(d->mCategories, addressee.d->mCategories)) {
339 qCDebug(KCONTACTS_LOG) <<
"categories differs";
343 if (d->mCustomFields != addressee.d->mCustomFields) {
344 qCDebug(KCONTACTS_LOG) <<
"custom differs";
347 if (d->mLangs != addressee.d->mLangs) {
348 qCDebug(KCONTACTS_LOG) <<
"langs differs";
351 if (d->mImpps != addressee.d->mImpps) {
352 qCDebug(KCONTACTS_LOG) <<
"impps differs";
355 if (d->mGender != addressee.d->mGender) {
356 qCDebug(KCONTACTS_LOG) <<
"gender differs";
359 if (d->mKind != addressee.d->mKind) {
360 qCDebug(KCONTACTS_LOG) <<
"kind differs";
363 if (!listEquals(d->mCalendarUrl, addressee.d->mCalendarUrl)) {
364 qCDebug(KCONTACTS_LOG) <<
"calendarUrl differs";
367 if (!listEquals(d->mSoundListExtra, addressee.d->mSoundListExtra)) {
368 qCDebug(KCONTACTS_LOG) <<
"Extra sound differs";
371 if (!listEquals(d->mPhotoExtraList, addressee.d->mPhotoExtraList)) {
372 qCDebug(KCONTACTS_LOG) <<
"Extra photo differs";
375 if (!listEquals(d->mLogoExtraList, addressee.d->mLogoExtraList)) {
376 qCDebug(KCONTACTS_LOG) <<
"Extra logo differs";
379 if (!listEquals(d->mUrlExtraList, addressee.d->mUrlExtraList)) {
380 qCDebug(KCONTACTS_LOG) <<
"Extra url differs";
383 if (!listEquals(d->mMembers, addressee.d->mMembers)) {
384 qCDebug(KCONTACTS_LOG) <<
"Extra url differs";
387 if (!listEquals(d->mRelationships, addressee.d->mRelationships)) {
388 qCDebug(KCONTACTS_LOG) <<
"Relationships differs";
391 if (!listEquals(d->mSources, addressee.d->mSources)) {
392 qCDebug(KCONTACTS_LOG) <<
"Sources differs";
396 if (!listEquals(d->mFieldGroupList, addressee.d->mFieldGroupList)) {
397 qCDebug(KCONTACTS_LOG) <<
"Field Groups differs";
401 if (!listEquals(d->mTitleExtraList, addressee.d->mTitleExtraList)) {
402 qCDebug(KCONTACTS_LOG) <<
"Extra TitleList differs";
406 if (!listEquals(d->mRoleExtraList, addressee.d->mRoleExtraList)) {
407 qCDebug(KCONTACTS_LOG) <<
"Extra RoleList differs";
411 if (!listEquals(d->mOrgExtraList, addressee.d->mOrgExtraList)) {
412 qCDebug(KCONTACTS_LOG) <<
"Extra Organization List differs";
416 if (!listEquals(d->mNickNameExtraList, addressee.d->mNickNameExtraList)) {
417 qCDebug(KCONTACTS_LOG) <<
"Extra NickName List differs";
421 if (!listEquals(d->mClientPidMapList, addressee.d->mClientPidMapList)) {
422 qCDebug(KCONTACTS_LOG) <<
"ClientPidMap List differs";
430 return !(a == *
this);
433bool Addressee::isEmpty()
const
455 return i18n(
"Unique Identifier");
460 if (name == d->mName) {
478void Addressee::setKind(
const QString &kind)
480 if (kind == d->mKind) {
488QString Addressee::kind()
const
493void Addressee::insertExtraSound(
const Sound &sound)
499Sound::List Addressee::extraSoundList()
const
501 return d->mSoundListExtra;
504void Addressee::insertExtraPhoto(
const Picture &picture)
507 d->mPhotoExtraList.
append(picture);
510Picture::List Addressee::extraPhotoList()
const
512 return d->mPhotoExtraList;
515void Addressee::insertExtraLogo(
const Picture &logo)
521Picture::List Addressee::extraLogoList()
const
523 return d->mLogoExtraList;
526void Addressee::setExtraSoundList(
const Sound::List &soundList)
529 d->mSoundListExtra = soundList;
532void Addressee::setExtraPhotoList(
const Picture::List &pictureList)
535 d->mPhotoExtraList = pictureList;
538void Addressee::setExtraLogoList(
const Picture::List &logoList)
541 d->mLogoExtraList = logoList;
548 d->mUrlExtraList.append(url);
552void Addressee::setExtraUrlList(
const ResourceLocatorUrl::List &urlList)
555 d->mUrlExtraList = urlList;
558ResourceLocatorUrl::List Addressee::extraUrlList()
const
560 return d->mUrlExtraList;
563void Addressee::insertSourceUrl(
const QUrl &url)
569void Addressee::setSourcesUrlList(
const QList<QUrl> &urlList)
572 d->mSources = urlList;
575QList<QUrl> Addressee::sourcesUrlList()
const
580FieldGroup::List Addressee::fieldGroupList()
const
582 return d->mFieldGroupList;
585void Addressee::setFieldGroupList(
const FieldGroup::List &fieldGroupList)
588 d->mFieldGroupList = fieldGroupList;
591void Addressee::insertFieldGroup(
const FieldGroup &fieldGroup)
593 if (fieldGroup.isValid()) {
596 d->mFieldGroupList.append(fieldGroup);
600ClientPidMap::List Addressee::clientPidMapList()
const
602 return d->mClientPidMapList;
605void Addressee::setClientPidMapList(
const ClientPidMap::List &clientpidmaplist)
608 d->mClientPidMapList = clientpidmaplist;
611void Addressee::insertClientPidMap(
const ClientPidMap &clientpidmap)
613 if (clientpidmap.isValid()) {
616 d->mClientPidMapList.append(clientpidmap);
620void Addressee::insertImpp(
const Impp &impp)
622 if (impp.isValid()) {
625 d->mImpps.append(impp);
629void Addressee::setImppList(
const Impp::List &imppList)
632 d->mImpps = imppList;
635Impp::List Addressee::imppList()
const
640void Addressee::insertCalendarUrl(
const CalendarUrl &calendarUrl)
644 if (calendarUrl.isValid()) {
645 d->mCalendarUrl.append(calendarUrl);
649CalendarUrl::List Addressee::calendarUrlList()
const
651 return d->mCalendarUrl;
656 if (formattedName == d->mFormattedName) {
661 d->mFormattedName = formattedName;
666 return d->mFormattedName;
671 return i18n(
"Formatted Name");
676 if (familyName == d->mFamilyName) {
681 d->mFamilyName = familyName;
686 return d->mFamilyName;
691 return i18n(
"Family Name");
696 if (givenName == d->mGivenName) {
701 d->mGivenName = givenName;
706 return d->mGivenName;
711 return i18n(
"Given Name");
716 if (additionalName == d->mAdditionalName) {
721 d->mAdditionalName = additionalName;
726 return d->mAdditionalName;
731 return i18n(
"Additional Names");
736 if (prefix == d->mPrefix) {
751 return i18n(
"Honorific Prefixes");
756 if (suffix == d->mSuffix) {
771 return i18n(
"Honorific Suffixes");
777 if (!d->mNickNameExtraList.isEmpty()) {
778 t = d->mNickNameExtraList.takeFirst();
779 t.setNickName(nickName);
780 d->mNickNameExtraList.prepend(t);
783 insertExtraNickName(t);
789 insertExtraNickName(nickName);
792void Addressee::insertExtraNickName(
const NickName &nickName)
794 if (nickName.isValid()) {
796 d->mNickNameExtraList.append(nickName);
800void Addressee::setExtraNickNameList(
const NickName::List &nickNameList)
803 d->mNickNameExtraList = nickNameList;
806NickName::List Addressee::extraNickNameList()
const
808 return d->mNickNameExtraList;
813 if (d->mNickNameExtraList.isEmpty()) {
816 return d->mNickNameExtraList.at(0).nickname();
822 return i18n(
"Nick Name");
827 if (birthday == d->mBirthday && d->mBirthdayWithTime == withTime) {
832 d->mBirthday = birthday;
834 d->mBirthday.setTime(
QTime());
836 d->mBirthdayWithTime = withTime;
841 if (birthday == d->mBirthday.date() && !d->mBirthdayWithTime) {
847 d->mBirthdayWithTime =
false;
855bool Addressee::birthdayHasTime()
const
857 return d->mBirthdayWithTime;
862 return i18n(
"Birthday");
867 return i18n(
"Home Address Street");
872 return i18n(
"Home Address Post Office Box");
877 return i18n(
"Home Address City");
882 return i18n(
"Home Address State");
887 return i18n(
"Home Address Zip Code");
892 return i18n(
"Home Address Country");
897 return i18n(
"Home Address Label");
902 return i18n(
"Business Address Street");
907 return i18n(
"Business Address Post Office Box");
912 return i18n(
"Business Address City");
917 return i18n(
"Business Address State");
922 return i18n(
"Business Address Zip Code");
927 return i18n(
"Business Address Country");
932 return i18n(
"Business Address Label");
937 return i18n(
"Home Phone");
942 return i18n(
"Business Phone");
947 return i18n(
"Mobile Phone");
952 return i18n(
"Home Fax");
957 return i18n(
"Business Fax");
962 return i18n(
"Car Phone");
972 return i18n(
"Pager");
977 return i18n(
"Email Address");
982 if (mailer == d->mMailer) {
997 return i18n(
"Mail Client");
1012 return d->mTimeZone;
1017 return i18n(
"Time Zone");
1022 if (geo == d->mGeo) {
1037 return i18n(
"Geographic Position");
1043 if (!d->mTitleExtraList.isEmpty()) {
1044 t = d->mTitleExtraList.takeFirst();
1046 d->mTitleExtraList.prepend(t);
1049 insertExtraTitle(title);
1055 insertExtraTitle(title);
1058void Addressee::insertExtraTitle(
const Title &title)
1060 if (title.isValid()) {
1062 d->mTitleExtraList.append(title);
1068 if (d->mTitleExtraList.isEmpty()) {
1071 return d->mTitleExtraList.at(0).title();
1075Title::List Addressee::extraTitleList()
const
1077 return d->mTitleExtraList;
1080void Addressee::setExtraTitleList(
const Title::List &urltitle)
1083 d->mTitleExtraList = urltitle;
1088 return i18nc(
"a person's title",
"Title");
1094 if (!d->mRoleExtraList.isEmpty()) {
1095 t = d->mRoleExtraList.takeFirst();
1097 d->mRoleExtraList.prepend(t);
1106 insertExtraRole(role);
1109void Addressee::insertExtraRole(
const Role &role)
1111 if (role.isValid()) {
1113 d->mRoleExtraList.append(role);
1117void Addressee::setExtraRoleList(
const Role::List &roleList)
1120 d->mRoleExtraList = roleList;
1123Role::List Addressee::extraRoleList()
const
1125 return d->mRoleExtraList;
1130 if (d->mRoleExtraList.isEmpty()) {
1133 return d->mRoleExtraList.at(0).role();
1139 return i18nc(
"of a person in an organization",
"Role");
1144 Org t(organization);
1145 if (!d->mOrgExtraList.isEmpty()) {
1146 t = d->mOrgExtraList.takeFirst();
1147 t.setOrganization(organization);
1148 d->mOrgExtraList.prepend(t);
1151 insertExtraOrganization(t);
1157 insertExtraOrganization(organization);
1160void Addressee::insertExtraOrganization(
const Org &organization)
1162 if (organization.isValid()) {
1164 d->mOrgExtraList.append(organization);
1168void Addressee::setExtraOrganizationList(
const Org::List &orgList)
1171 d->mOrgExtraList = orgList;
1174Org::List Addressee::extraOrganizationList()
const
1176 return d->mOrgExtraList;
1181 if (d->mOrgExtraList.isEmpty()) {
1184 return d->mOrgExtraList.at(0).organization();
1190 return i18n(
"Organization");
1195 if (department == d->mDepartment) {
1200 d->mDepartment = department;
1205 return d->mDepartment;
1210 return i18n(
"Department");
1215 if (note == d->mNote) {
1230 return i18n(
"Note");
1235 if (productId == d->mProductId) {
1240 d->mProductId = productId;
1245 return d->mProductId;
1250 return i18n(
"Product Identifier");
1255 if (revision == d->mRevision) {
1260 d->mRevision = revision;
1265 return d->mRevision;
1270 return i18n(
"Revision Date");
1275 if (sortString == d->mSortString) {
1280 d->mSortString = sortString;
1285 return d->mSortString;
1290 return i18n(
"Sort String");
1296 resourceLocator.setUrl(url);
1297 insertExtraUrl(resourceLocator);
1302 insertExtraUrl(url);
1307 if (d->mUrlExtraList.isEmpty()) {
1310 return d->mUrlExtraList.at(0);
1316 return i18n(
"Homepage");
1336 return i18n(
"Security Class");
1341 if (
logo == d->mLogo) {
1356 return i18n(
"Logo");
1361 if (photo == d->mPhoto) {
1376 return i18n(
"Photo");
1381 if (
sound == d->mSound) {
1396 return i18n(
"Sound");
1421 static QString spaceStr = QStringLiteral(
" ");
1422 static QString emptyStr = QStringLiteral(
"");
1423 AddresseeHelper *helper = AddresseeHelper::self();
1429 int rightOffset = parts.
count() - 1;
1432 while (rightOffset >= 0) {
1433 if (helper->containsSuffix(parts[rightOffset])) {
1434 suffix.prepend(parts[rightOffset] + (suffix.isEmpty() ? emptyStr : spaceStr));
1442 if (rightOffset < 0) {
1446 if (rightOffset - 1 >= 0 && helper->containsPrefix(parts[rightOffset - 1].toLower())) {
1447 setFamilyName(parts[rightOffset - 1] + spaceStr + parts[rightOffset]);
1450 if (helper->treatAsFamilyName()) {
1458 while (leftOffset < rightOffset) {
1459 if (helper->containsTitle(parts[leftOffset])) {
1460 prefix.append((prefix.isEmpty() ? emptyStr : spaceStr) + parts[leftOffset]);
1468 if (leftOffset < rightOffset) {
1474 while (leftOffset < rightOffset) {
1475 additionalName.append((additionalName.isEmpty() ? emptyStr : spaceStr) + parts[leftOffset]);
1485 int rightOffset = parts.
count() - 1;
1489 while (rightOffset >= 0) {
1490 if (helper->containsSuffix(parts[rightOffset])) {
1491 suffix.prepend(parts[rightOffset] + (suffix.isEmpty() ? emptyStr : spaceStr));
1499 if (rightOffset - 1 >= 0 && helper->containsPrefix(parts[rightOffset - 1].toLower())) {
1500 setFamilyName(parts[rightOffset - 1] + spaceStr + parts[rightOffset]);
1507 while (leftOffset < rightOffset) {
1508 if (helper->containsTitle(parts[leftOffset])) {
1509 prefix.append((prefix.isEmpty() ? emptyStr : spaceStr) + parts[leftOffset]);
1521 parts = part2.
split(spaceStr);
1524 rightOffset = parts.
count();
1528 while (leftOffset < rightOffset) {
1529 if (helper->containsTitle(parts[leftOffset])) {
1530 prefix.append((prefix.isEmpty() ? emptyStr : spaceStr) + parts[leftOffset]);
1538 if (leftOffset < rightOffset) {
1544 while (leftOffset < rightOffset) {
1545 additionalName.append((additionalName.isEmpty() ? emptyStr : spaceStr) + parts[leftOffset]);
1563 n = assembledName();
1573 return organization();
1586 return name.simplified();
1593 e = preferredEmail();
1602 if (realName().isEmpty()) {
1606 if (realName().indexOf(needQuotes) != -1) {
1620 const QString mailAddr = email.mail();
1621 auto it = std::find_if(d->mEmails.begin(), d->mEmails.end(), [&mailAddr](
const Email &e) {
1622 return e.mail() == mailAddr;
1624 if (it != d->mEmails.end()) {
1626 if (email.isPreferred()) {
1628 std::rotate(d->mEmails.begin(), it, it + 1);
1635 if (email.isPreferred()) {
1636 d->mEmails.prepend(email);
1638 d->mEmails.append(email);
1644 for (
int i = 0; i < d->mEmails.size(); ++i) {
1645 if (d->mEmails.at(i).mail() == email) {
1646 d->mEmails.removeAt(i);
1653 if (d->mEmails.isEmpty()) {
1656 return d->mEmails.first().mail();
1663 const int numberOfEmail = d->mEmails.
size();
1665 for (
int i = 0; i < numberOfEmail; ++i) {
1666 list << d->mEmails.
at(i).mail();
1672Email::List Addressee::emailList()
const
1680 const int numEmails = emails.size();
1681 d->mEmails.reserve(numEmails);
1682 for (
int i = 0; i < numEmails; ++i) {
1683 d->mEmails.append(
Email(emails.at(i)));
1688void Addressee::setEmailList(
const Email::List &list)
1696 for (
int i = 0; i < d->mLangs.size(); ++i) {
1697 if (d->mLangs.at(i).language() == language) {
1698 d->mLangs.removeAt(i);
1703void Addressee::setLangs(
const Lang::List &langs)
1711 const QString languageStr = language.language();
1717 auto it = std::find_if(d->mLangs.begin(), d->mLangs.end(), [&languageStr](
const Lang &lang) {
1718 return lang.language() == languageStr;
1720 if (it != d->mLangs.end()) {
1721 (*it).setParams(language.params());
1725 d->mLangs.append(language);
1733void Addressee::setGender(
const Gender &gender)
1735 if (gender == d->mGender) {
1740 d->mGender = gender;
1743Gender Addressee::gender()
const
1752 auto it = std::find_if(d->mPhoneNumbers.begin(), d->mPhoneNumbers.end(), [&
phoneNumber](
const PhoneNumber &pNumber) {
1753 return pNumber.id() == phoneNumber.id();
1755 if (it != d->mPhoneNumbers.end()) {
1760 if (!
phoneNumber.number().simplified().isEmpty()) {
1767 auto it = std::find_if(d->mPhoneNumbers.begin(), d->mPhoneNumbers.end(), [&
phoneNumber](
const PhoneNumber &p) {
1768 return p.id() == phoneNumber.id();
1771 if (it != d->mPhoneNumbers.end()) {
1772 d->mPhoneNumbers.erase(it);
1780 for (
const PhoneNumber &phone : d->mPhoneNumbers) {
1781 if (matchBinaryPattern(phone.type(), type)) {
1795 return d->mPhoneNumbers;
1801 d->mPhoneNumbers.clear();
1802 d->mPhoneNumbers = phoneNumbers;
1809 std::copy_if(d->mPhoneNumbers.cbegin(), d->mPhoneNumbers.cend(), std::back_inserter(list), [type](
const auto &phone) {
1810 return matchBinaryPattern(phone.type(), type);
1817 auto it = std::find_if(d->mPhoneNumbers.cbegin(), d->mPhoneNumbers.cend(), [&
id](
const PhoneNumber &phone) {
1818 return phone.id() == id;
1821 return it != d->mPhoneNumbers.cend() ? *it :
PhoneNumber{};
1828 auto it = std::find_if(d->mKeys.begin(), d->mKeys.end(), [&
key](
Key &existing) {
1829 return existing.id() == key.id();
1831 if (it != d->mKeys.end()) {
1834 d->mKeys.append(
key);
1840 auto it = std::remove_if(d->mKeys.begin(), d->mKeys.end(), [&
key](
const Key &k) {
1841 return k.id() == key.id();
1843 d->mKeys.erase(it, d->mKeys.end());
1848 for (
const auto &
key : d->mKeys) {
1849 if (
key.type() == type) {
1851 if (customTypeString.
isEmpty()) {
1854 if (
key.customTypeString() == customTypeString) {
1880 auto matchFunc = [type, &customTypeString](
const Key &
key) {
1881 if (
key.type() == type) {
1883 if (customTypeString.
isEmpty()) {
1886 if (
key.customTypeString() == customTypeString) {
1897 std::copy_if(d->mKeys.cbegin(), d->mKeys.cend(), std::back_inserter(list), matchFunc);
1904 auto it = std::find_if(d->mKeys.cbegin(), d->mKeys.cend(), [&
id](
const Key &
key) {
1905 return key.id() == id;
1908 return it != d->mKeys.cend() ? *it :
Key{};
1914 str += QStringLiteral(
" Uid: %1\n").
arg(uid());
1916 str += QStringLiteral(
" Name: %1\n").
arg(name());
1917 str += QStringLiteral(
" FormattedName: %1\n").
arg(formattedName());
1918 str += QStringLiteral(
" FamilyName: %1\n").
arg(familyName());
1919 str += QStringLiteral(
" GivenName: %1\n").
arg(givenName());
1920 str += QStringLiteral(
" AdditionalName: %1\n").
arg(additionalName());
1921 str += QStringLiteral(
" Prefix: %1\n").
arg(prefix());
1922 str += QStringLiteral(
" Suffix: %1\n").
arg(suffix());
1923 str += QStringLiteral(
" NickName: %1\n").
arg(nickName());
1924 str += QStringLiteral(
" Birthday: %1\n").
arg(birthday().
toString());
1925 str += QStringLiteral(
" Mailer: %1\n").
arg(mailer());
1927 str += QStringLiteral(
" Geo: %1\n").
arg(geo().
toString());
1928 str += QStringLiteral(
" Title: %1\n").
arg(title());
1929 str += QStringLiteral(
" Role: %1\n").
arg(role());
1930 str += QStringLiteral(
" Organization: %1\n").
arg(organization());
1931 str += QStringLiteral(
" Department: %1\n").
arg(department());
1932 str += QStringLiteral(
" Note: %1\n").
arg(note());
1933 str += QStringLiteral(
" ProductId: %1\n").
arg(productId());
1934 str += QStringLiteral(
" Revision: %1\n").
arg(revision().
toString());
1935 str += QStringLiteral(
" SortString: %1\n").
arg(sortString());
1936 str += QStringLiteral(
" Url: %1\n").
arg(url().url().url());
1939 str += QStringLiteral(
" Photo: %1\n").
arg(photo().
toString());
1941 str += QStringLiteral(
" Gender: %1\n").
arg(gender().
toString());
1942 str += QStringLiteral(
" Kind: %1\n").
arg(kind());
1945 const Email::List listEmail = d->mEmails;
1946 for (
const Email &email : listEmail) {
1947 str += email.toString();
1952 const Lang::List listLang = d->mLangs;
1953 for (
const Lang &lang : listLang) {
1954 str += lang.toString();
1960 for (
const auto &p : phones) {
1961 str += p.toString();
1967 for (
const auto &addr : addrList) {
1968 str += addr.toString();
1974 for (
const auto &k : keyList) {
1975 str += k.toString();
1992 auto it = std::find_if(d->mAddresses.begin(), d->mAddresses.end(), [&
address](
const Address &addr) {
1993 return addr.id() == address.id();
1995 if (it != d->mAddresses.end()) {
2000 d->mAddresses.append(
address);
2005 auto it = std::find_if(d->mAddresses.begin(), d->mAddresses.end(), [&
address](
const Address &addr) {
2006 return addr.id() == address.id();
2008 if (it != d->mAddresses.end()) {
2009 d->mAddresses.erase(it);
2016 d->mAddresses = addresses;
2022 for (
const Address &addr : d->mAddresses) {
2023 if (matchBinaryPattern(addr.type(), type)) {
2026 }
else if (
address.isEmpty()) {
2037 return d->mAddresses;
2044 std::copy_if(d->mAddresses.cbegin(), d->mAddresses.cend(), std::back_inserter(list), [type](
const Address &addr) {
2045 return matchBinaryPattern(addr.type(), type);
2053 auto it = std::find_if(d->mAddresses.cbegin(), d->mAddresses.cend(), [&
id](
const Address &addr) {
2054 return addr.id() == id;
2056 return it != d->mAddresses.cend() ? *it :
Address{};
2063 if (d->mCategories.contains(c)) {
2067 d->mCategories.append(c);
2072 if (d->mCategories.contains(category)) {
2073 d->mCategories.removeAll(category);
2079 return d->mCategories.contains(category);
2091 return d->mCategories;
2094void Addressee::insertMember(
const QString &member)
2098 if (d->mMembers.contains(member)) {
2102 d->mMembers.append(member);
2105void Addressee::setMembers(
const QStringList &m)
2111QStringList Addressee::members()
const
2116void Addressee::insertRelationship(
const Related &relation)
2120 if (d->mRelationships.contains(relation)) {
2124 d->mRelationships.
append(relation);
2127void Addressee::setRelationships(
const Related::List &c)
2130 d->mRelationships = c;
2133Related::List Addressee::relationships()
const
2135 return d->mRelationships;
2138static const auto VENDOR_ID = QStringLiteral(
"KADDRESSBOOK");
2139static const auto X_ANNIVERSARY = QStringLiteral(
"X-Anniversary");
2140static const auto X_ASSISTANTSNAME = QStringLiteral(
"X-AssistantsName");
2141static const auto BLOGFEED = QStringLiteral(
"BlogFeed");
2142static const auto X_MANAGERSNAME = QStringLiteral(
"X-ManagersName");
2143static const auto X_OFFICE = QStringLiteral(
"X-Office");
2144static const auto X_PROFESSION = QStringLiteral(
"X-Profession");
2145static const auto X_SPOUSESNAME = QStringLiteral(
"X-SpousesName");
2154 if (anniversary.isValid()) {
2163 return custom(VENDOR_ID, X_ASSISTANTSNAME);
2168 if (!assistantsName.isEmpty()) {
2169 insertCustom(VENDOR_ID, X_ASSISTANTSNAME, assistantsName);
2182 if (!blogFeed.isEmpty()) {
2191 return custom(VENDOR_ID, X_MANAGERSNAME);
2196 if (!managersName.isEmpty()) {
2205 return custom(VENDOR_ID, X_OFFICE);
2210 if (!office.isEmpty()) {
2219 return custom(VENDOR_ID, X_PROFESSION);
2224 if (!profession.isEmpty()) {
2233 return custom(VENDOR_ID, X_SPOUSESNAME);
2238 if (!spousesName.isEmpty()) {
2255 auto it = d->findByName(qualifiedName);
2256 if (it != d->mCustomFields.end()) {
2259 const CustomData newdata{qualifiedName, value};
2260 auto beforeIt = std::lower_bound(d->mCustomFields.begin(), d->mCustomFields.end(), newdata);
2261 d->mCustomFields.insert(beforeIt, newdata);
2268 auto it = d->findByName(qualifiedName);
2269 if (it != d->mCustomFields.end()) {
2270 d->mCustomFields.erase(it);
2277 auto it = d->findByName(qualifiedName);
2278 return it != d->mCustomFields.cend() ? it->value :
QString{};
2285 d->mCustomFields.
clear();
2298 if (!seen.
contains(qualifiedName)) {
2299 d->mCustomFields.push_back({qualifiedName, value});
2303 std::sort(d->mCustomFields.begin(), d->mCustomFields.end());
2309 result.
reserve(d->mCustomFields.size());
2312 for (
const auto &[name, value] : d->mCustomFields) {
2313 result << name + sep + value;
2345 sourceLevel context = TopLevel;
2346 bool inQuotedString =
false;
2347 int commentLevel = 0;
2350 for (
char *p =
address.data(); *p && !
stop; ++p) {
2355 inQuotedString = !inQuotedString;
2359 if (!inQuotedString) {
2360 context = InComment;
2367 if (!inQuotedString) {
2368 context = InAngleAddress;
2384 if (!inQuotedString) {
2406 if (commentLevel == 0) {
2427 case InAngleAddress:
2430 inQuotedString = !inQuotedString;
2434 if (!inQuotedString) {
2458 displayName = displayName.
trimmed();
2460 addrSpec = addrSpec.
trimmed();
2463 if (inQuotedString) {
2466 if (context == InComment) {
2469 if (context == InAngleAddress) {
2489 const unsigned int len = fullName.
length();
2494 fullName = fullName.
mid(1, len - 2);
2500 d->mChanged = value;
2503bool Addressee::changed()
const
2510 return QStringLiteral(
"text/directory");
2518 s << a.d->mFormattedName;
2519 s << a.d->mFamilyName;
2520 s << a.d->mGivenName;
2521 s << a.d->mAdditionalName;
2524 s << a.d->mBirthday;
2525 s << a.d->mBirthdayWithTime;
2527 s << a.d->mTimeZone;
2529 s << a.d->mDepartment;
2531 s << a.d->mProductId;
2532 s << a.d->mRevision;
2533 s << a.d->mSortString;
2538 s << a.d->mPhoneNumbers;
2539 s << a.d->mAddresses;
2541 s << a.d->mCategories;
2547 s << a.d->mCalendarUrl;
2548 s << a.d->mSoundListExtra;
2549 s << a.d->mPhotoExtraList;
2550 s << a.d->mLogoExtraList;
2551 s << a.d->mUrlExtraList;
2553 s << a.d->mRelationships;
2556 s << a.d->mFieldGroupList;
2557 s << a.d->mTitleExtraList;
2558 s << a.d->mRoleExtraList;
2559 s << a.d->mOrgExtraList;
2560 s << a.d->mNickNameExtraList;
2561 s << a.d->mClientPidMapList;
2571 s >> a.d->mFormattedName;
2572 s >> a.d->mFamilyName;
2573 s >> a.d->mGivenName;
2574 s >> a.d->mAdditionalName;
2577 s >> a.d->mBirthday;
2578 s >> a.d->mBirthdayWithTime;
2580 s >> a.d->mTimeZone;
2582 s >> a.d->mDepartment;
2584 s >> a.d->mProductId;
2585 s >> a.d->mRevision;
2586 s >> a.d->mSortString;
2591 s >> a.d->mPhoneNumbers;
2592 s >> a.d->mAddresses;
2594 s >> a.d->mCategories;
2602 s >> a.d->mCalendarUrl;
2603 s >> a.d->mSoundListExtra;
2604 s >> a.d->mPhotoExtraList;
2605 s >> a.d->mLogoExtraList;
2606 s >> a.d->mUrlExtraList;
2608 s >> a.d->mRelationships;
2611 s >> a.d->mFieldGroupList;
2612 s >> a.d->mTitleExtraList;
2613 s >> a.d->mRoleExtraList;
2614 s >> a.d->mOrgExtraList;
2615 s >> a.d->mNickNameExtraList;
2616 s >> a.d->mClientPidMapList;
2617 a.d->mEmpty =
false;
2622bool matchBinaryPattern(
int value,
int pattern)
2633 return pattern == (pattern & value);
2638bool listEquals(
const QList<L> &list,
const QList<L> &pattern)
2643 const int numberOfElement(
list.
count());
2644 for (
int i = 0; i < numberOfElement; ++i) {
2653bool listEquals(
const QStringList &list,
const QStringList &pattern)
2659 const int numberOfElement(
list.
count());
2660 for (
int i = 0; i < numberOfElement; ++i) {
2669void Addressee::setBirthdayProperty(
const QDateTime &birthday) {
2671 setBirthday(birthday, birthday.time().msecsSinceStartOfDay() != 0);
2674#include "moc_addressee.cpp"
void stop(Ekos::AlignState mode)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
StandardShortcut findByName(const QString &name)
bool isEmpty() const const
QByteArray trimmed() const const
QDate fromString(QStringView string, QStringView format, QCalendar cal)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
bool contains(const AT &value) const const
qsizetype count() const const
bool isEmpty() const const
void push_back(parameter_type value)
void reserve(qsizetype size)
qsizetype size() const const
QString & append(QChar ch)
QString arg(Args &&... args) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
QString fromUtf8(QByteArrayView str)
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
bool isNull() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QString simplified() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString toLower() const const
QByteArray toUtf8() const const
QString trimmed() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const