File indexing completed on 2024-11-24 04:44:27

0001 /*
0002     This file is part of oxaccess.
0003 
0004     SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "contactutils.h"
0010 
0011 #include "davutils.h"
0012 #include "oxutils.h"
0013 #include "users.h"
0014 
0015 #include <Akonadi/ContactGroupExpandJob>
0016 
0017 #include <QBuffer>
0018 #include <QDomElement>
0019 #include <QImage>
0020 #include <QRegularExpression>
0021 using namespace OXA;
0022 
0023 void OXA::ContactUtils::parseContact(const QDomElement &propElement, Object &object)
0024 {
0025     bool isDistributionList = false;
0026     QDomElement distributionListElement = propElement.firstChildElement(QStringLiteral("distributionlist_flag"));
0027     if (!distributionListElement.isNull()) {
0028         if (OXUtils::readBoolean(distributionListElement.text()) == true) {
0029             isDistributionList = true;
0030         }
0031     }
0032 
0033     if (isDistributionList) {
0034         KContacts::ContactGroup contactGroup;
0035 
0036         QDomElement element = propElement.firstChildElement();
0037         while (!element.isNull()) {
0038             const QString tagName = element.tagName();
0039             const QString text = OXUtils::readString(element.text());
0040 
0041             if (tagName == QLatin1StringView("displayname")) {
0042                 contactGroup.setName(text);
0043             } else if (tagName == QLatin1StringView("distributionlist")) {
0044                 QDomElement emailElement = element.firstChildElement();
0045                 while (!emailElement.isNull()) {
0046                     const QString tagName = emailElement.tagName();
0047                     const QString text = OXUtils::readString(emailElement.text());
0048 
0049                     if (tagName == QLatin1StringView("email")) {
0050                         const int emailField = OXUtils::readNumber(emailElement.attribute(QStringLiteral("emailfield")));
0051                         if (emailField == 0) { // internal data
0052                             KContacts::ContactGroup::Data data;
0053                             data.setName(OXUtils::readString(emailElement.attribute(QStringLiteral("displayname"))));
0054                             data.setEmail(text);
0055 
0056                             contactGroup.append(data);
0057                         } else { // external reference
0058                             // we convert them to internal data, seems like a more stable approach
0059                             KContacts::ContactGroup::Data data;
0060                             const qlonglong uid = OXUtils::readNumber(emailElement.attribute(QStringLiteral("id")));
0061 
0062                             const User user = Users::self()->lookupUid(uid);
0063                             if (user.isValid()) {
0064                                 data.setName(user.name());
0065                                 data.setEmail(user.email());
0066                             } else {
0067                                 // fallback: use the data from the element
0068                                 data.setName(OXUtils::readString(emailElement.attribute(QStringLiteral("displayname"))));
0069                                 data.setEmail(text);
0070                             }
0071 
0072                             contactGroup.append(data);
0073                         }
0074                     }
0075 
0076                     emailElement = emailElement.nextSiblingElement();
0077                 }
0078             }
0079             element = element.nextSiblingElement();
0080         }
0081 
0082         object.setContactGroup(contactGroup);
0083     } else {
0084         KContacts::Addressee contact;
0085         KContacts::Address homeAddress(KContacts::Address::Home);
0086         KContacts::Address workAddress(KContacts::Address::Work);
0087         KContacts::Address otherAddress(KContacts::Address::Dom);
0088 
0089         QDomElement element = propElement.firstChildElement();
0090         while (!element.isNull()) {
0091             const QString tagName = element.tagName();
0092             const QString text = OXUtils::readString(element.text());
0093 
0094             // name
0095             if (tagName == QLatin1StringView("title")) {
0096                 contact.setTitle(text);
0097             } else if (tagName == QLatin1StringView("first_name")) {
0098                 contact.setGivenName(text);
0099             } else if (tagName == QLatin1StringView("second_name")) {
0100                 contact.setAdditionalName(text);
0101             } else if (tagName == QLatin1StringView("last_name")) {
0102                 contact.setFamilyName(text);
0103             } else if (tagName == QLatin1StringView("suffix")) {
0104                 contact.setSuffix(text);
0105             } else if (tagName == QLatin1StringView("displayname")) {
0106                 contact.setFormattedName(text);
0107             } else if (tagName == QLatin1StringView("nickname")) {
0108                 contact.setNickName(text);
0109                 // dates
0110             } else if (tagName == QLatin1StringView("birthday")) {
0111                 contact.setBirthday(OXUtils::readDateTime(element.text()));
0112             } else if (tagName == QLatin1StringView("anniversary")) {
0113                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"),
0114                                      QStringLiteral("X-Anniversary"),
0115                                      OXUtils::readDateTime(element.text()).toString(Qt::ISODate));
0116             } else if (tagName == QLatin1StringView("spouse_name")) {
0117                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-SpousesName"), text);
0118                 // addresses
0119             } else if (tagName == QLatin1StringView("street")) {
0120                 homeAddress.setStreet(text);
0121             } else if (tagName == QLatin1StringView("postal_code")) {
0122                 homeAddress.setPostalCode(text);
0123             } else if (tagName == QLatin1StringView("city")) {
0124                 homeAddress.setLocality(text);
0125             } else if (tagName == QLatin1StringView("country")) {
0126                 homeAddress.setCountry(text);
0127             } else if (tagName == QLatin1StringView("state")) {
0128                 homeAddress.setRegion(text);
0129             } else if (tagName == QLatin1StringView("business_street")) {
0130                 workAddress.setStreet(text);
0131             } else if (tagName == QLatin1StringView("business_postal_code")) {
0132                 workAddress.setPostalCode(text);
0133             } else if (tagName == QLatin1StringView("business_city")) {
0134                 workAddress.setLocality(text);
0135             } else if (tagName == QLatin1StringView("business_country")) {
0136                 workAddress.setCountry(text);
0137             } else if (tagName == QLatin1StringView("business_state")) {
0138                 workAddress.setRegion(text);
0139             } else if (tagName == QLatin1StringView("second_street")) {
0140                 otherAddress.setStreet(text);
0141             } else if (tagName == QLatin1StringView("second_postal_code")) {
0142                 otherAddress.setPostalCode(text);
0143             } else if (tagName == QLatin1StringView("second_city")) {
0144                 otherAddress.setLocality(text);
0145             } else if (tagName == QLatin1StringView("second_country")) {
0146                 otherAddress.setCountry(text);
0147             } else if (tagName == QLatin1StringView("second_state")) {
0148                 otherAddress.setRegion(text);
0149             } else if (tagName == QLatin1StringView("defaultaddress")) {
0150                 const int number = text.toInt();
0151                 if (number == 1) {
0152                     workAddress.setType(workAddress.type() | KContacts::Address::Pref);
0153                 } else if (number == 2) {
0154                     homeAddress.setType(homeAddress.type() | KContacts::Address::Pref);
0155                 } else if (number == 3) {
0156                     otherAddress.setType(otherAddress.type() | KContacts::Address::Pref);
0157                 }
0158                 // further information
0159             } else if (tagName == QLatin1StringView("note")) {
0160                 contact.setNote(text);
0161             } else if (tagName == QLatin1StringView("url")) {
0162                 KContacts::ResourceLocatorUrl url;
0163                 url.setUrl(QUrl(text));
0164                 contact.setUrl(url);
0165             } else if (tagName == QLatin1StringView("image1")) {
0166                 const QByteArray data = text.toUtf8();
0167                 contact.setPhoto(KContacts::Picture(QImage::fromData(QByteArray::fromBase64(data))));
0168                 // company information
0169             } else if (tagName == QLatin1StringView("company")) {
0170                 contact.setOrganization(text);
0171             } else if (tagName == QLatin1StringView("department")) {
0172                 contact.setDepartment(text);
0173             } else if (tagName == QLatin1StringView("assistants_name")) {
0174                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-AssistantsName"), text);
0175             } else if (tagName == QLatin1StringView("managers_name")) {
0176                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-ManagersName"), text);
0177             } else if (tagName == QLatin1StringView("position")) {
0178                 contact.setRole(text);
0179             } else if (tagName == QLatin1StringView("profession")) {
0180                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Profession"), text);
0181             } else if (tagName == QLatin1StringView("room_number")) {
0182                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Office"), text);
0183                 // communication
0184             } else if (tagName == QLatin1StringView("email1")) {
0185                 KContacts::Email email(text);
0186                 email.setPreferred(true);
0187                 contact.addEmail(email);
0188             } else if (tagName == QLatin1StringView("email2") || tagName == QLatin1StringView("email3")) {
0189                 KContacts::Email email(text);
0190                 contact.addEmail(email);
0191             } else if (tagName == QLatin1StringView("mobile1")) {
0192                 contact.insertPhoneNumber(KContacts::PhoneNumber(text, KContacts::PhoneNumber::Cell));
0193             } else if (tagName == QLatin1StringView("instant_messenger")) {
0194                 contact.insertCustom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-IMAddress"), text);
0195             } else if (tagName.startsWith(QLatin1StringView("phone_"))) {
0196                 KContacts::PhoneNumber number;
0197                 number.setNumber(text);
0198                 bool supportedType = false;
0199 
0200                 if (tagName.endsWith(QLatin1StringView("_business"))) {
0201                     number.setType(KContacts::PhoneNumber::Work);
0202                     supportedType = true;
0203                 } else if (tagName.endsWith(QLatin1StringView("_home"))) {
0204                     number.setType(KContacts::PhoneNumber::Home);
0205                     supportedType = true;
0206                 } else if (tagName.endsWith(QLatin1StringView("_other"))) {
0207                     number.setType(KContacts::PhoneNumber::Voice);
0208                     supportedType = true;
0209                 } else if (tagName.endsWith(QLatin1StringView("_car"))) {
0210                     number.setType(KContacts::PhoneNumber::Car);
0211                     supportedType = true;
0212                 }
0213 
0214                 if (supportedType) {
0215                     contact.insertPhoneNumber(number);
0216                 }
0217             } else if (tagName.startsWith(QLatin1StringView("fax_"))) {
0218                 KContacts::PhoneNumber number;
0219                 number.setNumber(text);
0220                 bool supportedType = false;
0221 
0222                 if (tagName.endsWith(QLatin1StringView("_business"))) {
0223                     number.setType(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Work);
0224                     supportedType = true;
0225                 } else if (tagName.endsWith(QLatin1StringView("_home"))) {
0226                     number.setType(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Home);
0227                     supportedType = true;
0228                 } else if (tagName.endsWith(QLatin1StringView("_other"))) {
0229                     number.setType(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Voice);
0230                     supportedType = true;
0231                 }
0232 
0233                 if (supportedType) {
0234                     contact.insertPhoneNumber(number);
0235                 }
0236             } else if (tagName == QLatin1StringView("pager")) {
0237                 contact.insertPhoneNumber(KContacts::PhoneNumber(text, KContacts::PhoneNumber::Pager));
0238             } else if (tagName == QLatin1StringView("categories")) {
0239                 contact.setCategories(text.split(QRegularExpression(QStringLiteral(",\\s*"))));
0240             }
0241 
0242             element = element.nextSiblingElement();
0243         }
0244 
0245         if (!homeAddress.isEmpty()) {
0246             contact.insertAddress(homeAddress);
0247         }
0248         if (!workAddress.isEmpty()) {
0249             contact.insertAddress(workAddress);
0250         }
0251         if (!otherAddress.isEmpty()) {
0252             contact.insertAddress(otherAddress);
0253         }
0254 
0255         object.setContact(contact);
0256     }
0257 }
0258 
0259 void OXA::ContactUtils::addContactElements(QDomDocument &document, QDomElement &propElement, const Object &object, void *preloadedData)
0260 {
0261     if (!object.contact().isEmpty()) {
0262         // it is a contact payload
0263 
0264         const KContacts::Addressee contact = object.contact();
0265 
0266         // name
0267         DAVUtils::addOxElement(document, propElement, QStringLiteral("title"), OXUtils::writeString(contact.title()));
0268         DAVUtils::addOxElement(document, propElement, QStringLiteral("first_name"), OXUtils::writeString(contact.givenName()));
0269         DAVUtils::addOxElement(document, propElement, QStringLiteral("second_name"), OXUtils::writeString(contact.additionalName()));
0270         DAVUtils::addOxElement(document, propElement, QStringLiteral("last_name"), OXUtils::writeString(contact.familyName()));
0271         DAVUtils::addOxElement(document, propElement, QStringLiteral("suffix"), OXUtils::writeString(contact.suffix()));
0272         DAVUtils::addOxElement(document, propElement, QStringLiteral("displayname"), OXUtils::writeString(contact.formattedName()));
0273         DAVUtils::addOxElement(document, propElement, QStringLiteral("nickname"), OXUtils::writeString(contact.nickName()));
0274 
0275         // dates
0276         if (contact.birthday().date().isValid()) {
0277             DAVUtils::addOxElement(document, propElement, QStringLiteral("birthday"), OXUtils::writeDate(contact.birthday().date()));
0278         } else {
0279             DAVUtils::addOxElement(document, propElement, QStringLiteral("birthday"));
0280         }
0281 
0282         // since QDateTime::to/fromString() doesn't carry timezone information, we have to fake it here
0283         const QDate anniversary = QDate::fromString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Anniversary")), Qt::ISODate);
0284         if (anniversary.isValid()) {
0285             DAVUtils::addOxElement(document, propElement, QStringLiteral("anniversary"), OXUtils::writeDate(anniversary));
0286         } else {
0287             DAVUtils::addOxElement(document, propElement, QStringLiteral("anniversary"));
0288         }
0289         DAVUtils::addOxElement(document,
0290                                propElement,
0291                                QStringLiteral("spouse_name"),
0292                                OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-SpousesName"))));
0293 
0294         // addresses
0295         const KContacts::Address homeAddress = contact.address(KContacts::Address::Home);
0296         if (!homeAddress.isEmpty()) {
0297             DAVUtils::addOxElement(document, propElement, QStringLiteral("street"), OXUtils::writeString(homeAddress.street()));
0298             DAVUtils::addOxElement(document, propElement, QStringLiteral("postal_code"), OXUtils::writeString(homeAddress.postalCode()));
0299             DAVUtils::addOxElement(document, propElement, QStringLiteral("city"), OXUtils::writeString(homeAddress.locality()));
0300             DAVUtils::addOxElement(document, propElement, QStringLiteral("state"), OXUtils::writeString(homeAddress.region()));
0301             DAVUtils::addOxElement(document, propElement, QStringLiteral("country"), OXUtils::writeString(homeAddress.country()));
0302         }
0303         const KContacts::Address workAddress = contact.address(KContacts::Address::Work);
0304         if (!workAddress.isEmpty()) {
0305             DAVUtils::addOxElement(document, propElement, QStringLiteral("business_street"), OXUtils::writeString(workAddress.street()));
0306             DAVUtils::addOxElement(document, propElement, QStringLiteral("business_postal_code"), OXUtils::writeString(workAddress.postalCode()));
0307             DAVUtils::addOxElement(document, propElement, QStringLiteral("business_city"), OXUtils::writeString(workAddress.locality()));
0308             DAVUtils::addOxElement(document, propElement, QStringLiteral("business_state"), OXUtils::writeString(workAddress.region()));
0309             DAVUtils::addOxElement(document, propElement, QStringLiteral("business_country"), OXUtils::writeString(workAddress.country()));
0310         }
0311         const KContacts::Address otherAddress = contact.address(KContacts::Address::Dom);
0312         if (!otherAddress.isEmpty()) {
0313             DAVUtils::addOxElement(document, propElement, QStringLiteral("second_street"), OXUtils::writeString(otherAddress.street()));
0314             DAVUtils::addOxElement(document, propElement, QStringLiteral("second_postal_code"), OXUtils::writeString(otherAddress.postalCode()));
0315             DAVUtils::addOxElement(document, propElement, QStringLiteral("second_city"), OXUtils::writeString(otherAddress.locality()));
0316             DAVUtils::addOxElement(document, propElement, QStringLiteral("second_state"), OXUtils::writeString(otherAddress.region()));
0317             DAVUtils::addOxElement(document, propElement, QStringLiteral("second_country"), OXUtils::writeString(otherAddress.country()));
0318         }
0319 
0320         // further information
0321         DAVUtils::addOxElement(document, propElement, QStringLiteral("note"), OXUtils::writeString(contact.note()));
0322         DAVUtils::addOxElement(document, propElement, QStringLiteral("url"), OXUtils::writeString(contact.url().url().url()));
0323 
0324         // image
0325         const KContacts::Picture photo = contact.photo();
0326         if (!photo.data().isNull()) {
0327             QByteArray imageData;
0328             QBuffer buffer(&imageData);
0329             buffer.open(QIODevice::WriteOnly);
0330 
0331             QString contentType;
0332             if (!photo.data().hasAlphaChannel()) {
0333                 photo.data().save(&buffer, "JPEG");
0334                 contentType = QStringLiteral("image/jpg");
0335             } else {
0336                 photo.data().save(&buffer, "PNG");
0337                 contentType = QStringLiteral("image/png");
0338             }
0339 
0340             buffer.close();
0341 
0342             DAVUtils::addOxElement(document, propElement, QStringLiteral("image1"), QString::fromLatin1(imageData.toBase64()));
0343             DAVUtils::addOxElement(document, propElement, QStringLiteral("image_content_type"), contentType);
0344         } else {
0345             DAVUtils::addOxElement(document, propElement, QStringLiteral("image1"));
0346         }
0347 
0348         // company information
0349         DAVUtils::addOxElement(document, propElement, QStringLiteral("company"), OXUtils::writeString(contact.organization()));
0350         DAVUtils::addOxElement(document, propElement, QStringLiteral("department"), OXUtils::writeString(contact.department()));
0351         DAVUtils::addOxElement(document,
0352                                propElement,
0353                                QStringLiteral("assistants_name"),
0354                                OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-AssistantsName"))));
0355         DAVUtils::addOxElement(document,
0356                                propElement,
0357                                QStringLiteral("managers_name"),
0358                                OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-ManagersName"))));
0359         DAVUtils::addOxElement(document, propElement, QStringLiteral("position"), OXUtils::writeString(contact.role()));
0360         DAVUtils::addOxElement(document,
0361                                propElement,
0362                                QStringLiteral("profession"),
0363                                OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Profession"))));
0364         DAVUtils::addOxElement(document,
0365                                propElement,
0366                                QStringLiteral("room_number"),
0367                                OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-Office"))));
0368 
0369         // communication
0370         const QStringList emails = contact.emails();
0371         for (int i = 0; i < 3 && i < emails.count(); ++i) {
0372             DAVUtils::addOxElement(document, propElement, QStringLiteral("email%1").arg(i + 1), OXUtils::writeString(emails.at(i)));
0373         }
0374 
0375         DAVUtils::addOxElement(document,
0376                                propElement,
0377                                QStringLiteral("mobile1"),
0378                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Cell).number()));
0379         DAVUtils::addOxElement(document,
0380                                propElement,
0381                                QStringLiteral("instant_messenger"),
0382                                OXUtils::writeString(contact.custom(QStringLiteral("KADDRESSBOOK"), QStringLiteral("X-IMAddress"))));
0383 
0384         DAVUtils::addOxElement(document,
0385                                propElement,
0386                                QStringLiteral("phone_business"),
0387                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Work).number()));
0388         DAVUtils::addOxElement(document,
0389                                propElement,
0390                                QStringLiteral("phone_home"),
0391                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Home).number()));
0392         DAVUtils::addOxElement(document,
0393                                propElement,
0394                                QStringLiteral("phone_other"),
0395                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Voice).number()));
0396         DAVUtils::addOxElement(document,
0397                                propElement,
0398                                QStringLiteral("phone_car"),
0399                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Car).number()));
0400         DAVUtils::addOxElement(document,
0401                                propElement,
0402                                QStringLiteral("fax_business"),
0403                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Work).number()));
0404         DAVUtils::addOxElement(document,
0405                                propElement,
0406                                QStringLiteral("fax_home"),
0407                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Home).number()));
0408         DAVUtils::addOxElement(document,
0409                                propElement,
0410                                QStringLiteral("fax_other"),
0411                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Fax | KContacts::PhoneNumber::Voice).number()));
0412 
0413         DAVUtils::addOxElement(document,
0414                                propElement,
0415                                QStringLiteral("pager"),
0416                                OXUtils::writeString(contact.phoneNumber(KContacts::PhoneNumber::Pager).number()));
0417 
0418         DAVUtils::addOxElement(document, propElement, QStringLiteral("categories"), OXUtils::writeString(contact.categories().join(QLatin1Char(','))));
0419     } else {
0420         // it is a distribution list payload
0421 
0422         const KContacts::ContactGroup contactGroup = object.contactGroup();
0423 
0424         DAVUtils::addOxElement(document, propElement, QStringLiteral("displayname"), OXUtils::writeString(contactGroup.name()));
0425         DAVUtils::addOxElement(document, propElement, QStringLiteral("last_name"), OXUtils::writeString(contactGroup.name()));
0426         DAVUtils::addOxElement(document, propElement, QStringLiteral("distributionlist_flag"), OXUtils::writeBoolean(true));
0427 
0428         QDomElement distributionList = DAVUtils::addOxElement(document, propElement, QStringLiteral("distributionlist"));
0429 
0430         if (preloadedData) {
0431             // the contact group contains contact references that has been preloaded
0432             auto contacts = static_cast<KContacts::Addressee::List *>(preloadedData);
0433             for (const KContacts::Addressee &contact : *contacts) {
0434                 QDomElement email = DAVUtils::addOxElement(document, distributionList, QStringLiteral("email"), OXUtils::writeString(contact.preferredEmail()));
0435 
0436                 DAVUtils::setOxAttribute(email, QStringLiteral("folder_id"), OXUtils::writeNumber(0));
0437                 DAVUtils::setOxAttribute(email, QStringLiteral("emailfield"), OXUtils::writeNumber(0));
0438                 DAVUtils::setOxAttribute(email, QStringLiteral("id"), OXUtils::writeNumber(0));
0439                 DAVUtils::setOxAttribute(email, QStringLiteral("displayname"), OXUtils::writeString(contact.realName()));
0440             }
0441 
0442             delete contacts;
0443         } else {
0444             // the contact group contains only internal contact data
0445             for (int i = 0; i < contactGroup.dataCount(); ++i) {
0446                 const KContacts::ContactGroup::Data &data = contactGroup.data(i);
0447                 QDomElement email = DAVUtils::addOxElement(document, distributionList, QStringLiteral("email"), OXUtils::writeString(data.email()));
0448 
0449                 DAVUtils::setOxAttribute(email, QStringLiteral("folder_id"), OXUtils::writeNumber(0));
0450                 DAVUtils::setOxAttribute(email, QStringLiteral("emailfield"), OXUtils::writeNumber(0));
0451                 DAVUtils::setOxAttribute(email, QStringLiteral("id"), OXUtils::writeNumber(0));
0452                 DAVUtils::setOxAttribute(email, QStringLiteral("displayname"), OXUtils::writeString(data.name()));
0453             }
0454         }
0455     }
0456 }
0457 
0458 KJob *OXA::ContactUtils::preloadJob(const Object &object)
0459 {
0460     auto job = new Akonadi::ContactGroupExpandJob(object.contactGroup());
0461     return job;
0462 }
0463 
0464 void *OXA::ContactUtils::preloadData(const Object &, KJob *job)
0465 {
0466     auto expandJob = qobject_cast<Akonadi::ContactGroupExpandJob *>(job);
0467     Q_ASSERT(expandJob);
0468 
0469     return new KContacts::Addressee::List(expandJob->contacts());
0470 }