File indexing completed on 2024-05-19 05:11:23
0001 /* 0002 SPDX-FileCopyrightText: 2007 Till Adam <adam@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "akonadi_serializer_addressee.h" 0008 0009 #include <Akonadi/AbstractDifferencesReporter> 0010 #include <Akonadi/Item> 0011 0012 #include "serializer_debug.h" 0013 #include <KContacts/Addressee> 0014 #include <KLocalizedString> 0015 #include <QIODevice> 0016 0017 using namespace Akonadi; 0018 0019 //// ItemSerializerPlugin interface 0020 0021 // FIXME: these values map to Akonadi::ContactParts::Standard and 0022 // Akonadi::ContactParts::Lookup from AkonadiContact library. We don't use those 0023 // symbols here, because AkonadiContact library links to Qt5WebEngine, which when 0024 // loaded tries to initialize OpenGL. When this plugin gets loaded by Akonadi 0025 // from KRunner, it happens in a non-GUI thread, leading to a crash in Qt5WebEngine. 0026 #define CONTACTPART_STANDARD "CONTACT_STANDARD" 0027 #define CONTACTPART_LOOKUP "CONTACT_LOOKUP" 0028 0029 bool SerializerPluginAddressee::deserialize(Item &item, const QByteArray &label, QIODevice &data, int version) 0030 { 0031 Q_UNUSED(version) 0032 0033 KContacts::Addressee addr; 0034 if (label == Item::FullPayload) { 0035 addr = m_converter.parseVCard(data.readAll()); 0036 } else if (label == CONTACTPART_STANDARD) { 0037 addr = m_converter.parseVCard(data.readAll()); 0038 0039 // remove pictures and sound 0040 addr.setPhoto(KContacts::Picture()); 0041 addr.setLogo(KContacts::Picture()); 0042 addr.setSound(KContacts::Sound()); 0043 } else if (label == CONTACTPART_LOOKUP) { 0044 const KContacts::Addressee temp = m_converter.parseVCard(data.readAll()); 0045 0046 // copy only uid, name and email addresses 0047 addr.setUid(temp.uid()); 0048 addr.setPrefix(temp.prefix()); 0049 addr.setGivenName(temp.givenName()); 0050 addr.setAdditionalName(temp.additionalName()); 0051 addr.setFamilyName(temp.familyName()); 0052 addr.setSuffix(temp.suffix()); 0053 addr.setEmails(temp.emails()); 0054 } else { 0055 return false; 0056 } 0057 0058 if (!addr.isEmpty()) { 0059 item.setPayload<KContacts::Addressee>(addr); 0060 } else { 0061 qCWarning(AKONADI_SERIALIZER_CONTACT_LOG) << "Empty addressee object!"; 0062 } 0063 0064 return true; 0065 } 0066 0067 void SerializerPluginAddressee::serialize(const Item &item, const QByteArray &label, QIODevice &data, int &version) 0068 { 0069 Q_UNUSED(version) 0070 0071 if (label != Item::FullPayload && label != CONTACTPART_STANDARD && label != CONTACTPART_LOOKUP) { 0072 return; 0073 } 0074 0075 if (!item.hasPayload<KContacts::Addressee>()) { 0076 return; 0077 } 0078 0079 KContacts::Addressee addr; 0080 KContacts::Addressee temp; 0081 0082 temp = item.payload<KContacts::Addressee>(); 0083 0084 if (label == Item::FullPayload) { 0085 addr = temp; 0086 } else if (label == CONTACTPART_STANDARD) { 0087 addr = temp; 0088 0089 // remove pictures and sound 0090 addr.setPhoto(KContacts::Picture()); 0091 addr.setLogo(KContacts::Picture()); 0092 addr.setSound(KContacts::Sound()); 0093 } else if (label == CONTACTPART_LOOKUP) { 0094 // copy only uid, name and email addresses 0095 addr.setUid(temp.uid()); 0096 addr.setPrefix(temp.prefix()); 0097 addr.setGivenName(temp.givenName()); 0098 addr.setAdditionalName(temp.additionalName()); 0099 addr.setFamilyName(temp.familyName()); 0100 addr.setSuffix(temp.suffix()); 0101 addr.setEmails(temp.emails()); 0102 } 0103 0104 data.write(m_converter.createVCard(addr)); 0105 } 0106 0107 //// DifferencesAlgorithmInterface interface 0108 0109 static bool compareString(const QString &left, const QString &right) 0110 { 0111 if (left.isEmpty() && right.isEmpty()) { 0112 return true; 0113 } else { 0114 return left == right; 0115 } 0116 } 0117 0118 static QString toString(const KContacts::PhoneNumber &phoneNumber) 0119 { 0120 return phoneNumber.number(); 0121 } 0122 0123 static QString toString(const KContacts::Address &address) 0124 { 0125 return address.toString(); 0126 } 0127 0128 static QString toString(const QString &value) 0129 { 0130 return value; 0131 } 0132 0133 template<class T> 0134 static void compareList(Akonadi::AbstractDifferencesReporter *reporter, const QString &id, const QList<T> &left, const QList<T> &right) 0135 { 0136 for (int i = 0; i < left.count(); ++i) { 0137 if (!right.contains(left[i])) { 0138 reporter->addProperty(AbstractDifferencesReporter::AdditionalLeftMode, id, toString(left[i]), QString()); 0139 } 0140 } 0141 0142 for (int i = 0; i < right.count(); ++i) { 0143 if (!left.contains(right[i])) { 0144 reporter->addProperty(AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString(right[i])); 0145 } 0146 } 0147 } 0148 0149 template<class T> 0150 static void compareVector(Akonadi::AbstractDifferencesReporter *reporter, const QString &id, const QList<T> &left, const QList<T> &right) 0151 { 0152 for (int i = 0; i < left.count(); ++i) { 0153 if (!right.contains(left[i])) { 0154 reporter->addProperty(AbstractDifferencesReporter::AdditionalLeftMode, id, toString(left[i]), QString()); 0155 } 0156 } 0157 0158 for (int i = 0; i < right.count(); ++i) { 0159 if (!left.contains(right[i])) { 0160 reporter->addProperty(AbstractDifferencesReporter::AdditionalRightMode, id, QString(), toString(right[i])); 0161 } 0162 } 0163 } 0164 0165 void SerializerPluginAddressee::compare(Akonadi::AbstractDifferencesReporter *reporter, const Akonadi::Item &leftItem, const Akonadi::Item &rightItem) 0166 { 0167 Q_ASSERT(reporter); 0168 Q_ASSERT(leftItem.hasPayload<KContacts::Addressee>()); 0169 Q_ASSERT(rightItem.hasPayload<KContacts::Addressee>()); 0170 0171 reporter->setLeftPropertyValueTitle(i18n("Changed Contact")); 0172 reporter->setRightPropertyValueTitle(i18n("Conflicting Contact")); 0173 0174 const auto leftContact = leftItem.payload<KContacts::Addressee>(); 0175 const auto rightContact = rightItem.payload<KContacts::Addressee>(); 0176 0177 if (!compareString(leftContact.uid(), rightContact.uid())) { 0178 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::uidLabel(), leftContact.uid(), rightContact.uid()); 0179 } 0180 0181 if (!compareString(leftContact.name(), rightContact.name())) { 0182 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::nameLabel(), leftContact.name(), rightContact.name()); 0183 } 0184 0185 if (!compareString(leftContact.formattedName(), rightContact.formattedName())) { 0186 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0187 KContacts::Addressee::formattedNameLabel(), 0188 leftContact.formattedName(), 0189 rightContact.formattedName()); 0190 } 0191 0192 if (!compareString(leftContact.familyName(), rightContact.familyName())) { 0193 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0194 KContacts::Addressee::familyNameLabel(), 0195 leftContact.familyName(), 0196 rightContact.familyName()); 0197 } 0198 0199 if (!compareString(leftContact.givenName(), rightContact.givenName())) { 0200 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0201 KContacts::Addressee::givenNameLabel(), 0202 leftContact.givenName(), 0203 rightContact.givenName()); 0204 } 0205 0206 if (!compareString(leftContact.additionalName(), rightContact.additionalName())) { 0207 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0208 KContacts::Addressee::additionalNameLabel(), 0209 leftContact.additionalName(), 0210 rightContact.additionalName()); 0211 } 0212 0213 if (!compareString(leftContact.prefix(), rightContact.prefix())) { 0214 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::prefixLabel(), leftContact.prefix(), rightContact.prefix()); 0215 } 0216 0217 if (!compareString(leftContact.suffix(), rightContact.suffix())) { 0218 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::suffixLabel(), leftContact.suffix(), rightContact.suffix()); 0219 } 0220 0221 if (!compareString(leftContact.nickName(), rightContact.nickName())) { 0222 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0223 KContacts::Addressee::nickNameLabel(), 0224 leftContact.nickName(), 0225 rightContact.nickName()); 0226 } 0227 0228 if (leftContact.birthday() != rightContact.birthday()) { 0229 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0230 KContacts::Addressee::birthdayLabel(), 0231 leftContact.birthday().toString(), 0232 rightContact.birthday().toString()); 0233 } 0234 0235 if (!compareString(leftContact.mailer(), rightContact.mailer())) { 0236 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::mailerLabel(), leftContact.mailer(), rightContact.mailer()); 0237 } 0238 0239 if (leftContact.timeZone() != rightContact.timeZone()) { 0240 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0241 KContacts::Addressee::timeZoneLabel(), 0242 leftContact.timeZone().toString(), 0243 rightContact.timeZone().toString()); 0244 } 0245 0246 if (leftContact.geo() != rightContact.geo()) { 0247 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0248 KContacts::Addressee::geoLabel(), 0249 leftContact.geo().toString(), 0250 rightContact.geo().toString()); 0251 } 0252 0253 if (!compareString(leftContact.title(), rightContact.title())) { 0254 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::titleLabel(), leftContact.title(), rightContact.title()); 0255 } 0256 0257 if (!compareString(leftContact.role(), rightContact.role())) { 0258 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::roleLabel(), leftContact.role(), rightContact.role()); 0259 } 0260 0261 if (!compareString(leftContact.organization(), rightContact.organization())) { 0262 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0263 KContacts::Addressee::organizationLabel(), 0264 leftContact.organization(), 0265 rightContact.organization()); 0266 } 0267 0268 if (!compareString(leftContact.note(), rightContact.note())) { 0269 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, KContacts::Addressee::noteLabel(), leftContact.note(), rightContact.note()); 0270 } 0271 0272 if (!compareString(leftContact.productId(), rightContact.productId())) { 0273 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0274 KContacts::Addressee::productIdLabel(), 0275 leftContact.productId(), 0276 rightContact.productId()); 0277 } 0278 0279 if (!compareString(leftContact.sortString(), rightContact.sortString())) { 0280 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0281 KContacts::Addressee::sortStringLabel(), 0282 leftContact.sortString(), 0283 rightContact.sortString()); 0284 } 0285 0286 if (leftContact.secrecy() != rightContact.secrecy()) { 0287 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0288 KContacts::Addressee::secrecyLabel(), 0289 leftContact.secrecy().toString(), 0290 rightContact.secrecy().toString()); 0291 } 0292 0293 if (leftContact.url() != rightContact.url()) { 0294 reporter->addProperty(AbstractDifferencesReporter::ConflictMode, 0295 KContacts::Addressee::urlLabel(), 0296 leftContact.url().url().toDisplayString(), 0297 rightContact.url().url().toDisplayString()); 0298 } 0299 0300 compareList(reporter, i18n("Emails"), leftContact.emails(), rightContact.emails()); 0301 compareVector(reporter, i18n("Phone Numbers"), leftContact.phoneNumbers(), rightContact.phoneNumbers()); 0302 compareVector(reporter, i18n("Addresses"), leftContact.addresses(), rightContact.addresses()); 0303 0304 // TODO: logo/photo/custom entries 0305 } 0306 0307 //// GidExtractorInterface 0308 0309 QString SerializerPluginAddressee::extractGid(const Item &item) const 0310 { 0311 if (!item.hasPayload<KContacts::Addressee>()) { 0312 return {}; 0313 } 0314 return item.payload<KContacts::Addressee>().uid(); 0315 } 0316 0317 #include "moc_akonadi_serializer_addressee.cpp"