File indexing completed on 2024-12-22 04:57:02
0001 /* 0002 SPDX-FileCopyrightText: 2015-2017 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ewsitem.h" 0008 0009 #include <QXmlStreamReader> 0010 #include <QXmlStreamWriter> 0011 0012 #include "ewsattachment.h" 0013 #include "ewsattendee.h" 0014 #include "ewsclient_debug.h" 0015 #include "ewsitembase_p.h" 0016 #include "ewsmailbox.h" 0017 #include "ewsoccurrence.h" 0018 #include "ewsrecurrence.h" 0019 #include "ewsxml.h" 0020 0021 #define D_PTR EwsItemPrivate *d = reinterpret_cast<EwsItemPrivate *>(this->d.data()); 0022 #define D_CPTR const EwsItemPrivate *d = reinterpret_cast<const EwsItemPrivate *>(this->d.data()); 0023 0024 class EwsItemPrivate : public EwsItemBasePrivate 0025 { 0026 public: 0027 typedef EwsXml<EwsItemFields> Reader; 0028 0029 EwsItemPrivate(); 0030 EwsItemPrivate(const EwsItemBasePrivate &other); 0031 EwsItemBasePrivate *clone() const override 0032 { 0033 return new EwsItemPrivate(*this); 0034 } 0035 0036 static bool bodyReader(QXmlStreamReader &reader, QVariant &val); 0037 static bool messageHeadersReader(QXmlStreamReader &reader, QVariant &val); 0038 static bool mailboxReader(QXmlStreamReader &reader, QVariant &val); 0039 static bool recipientsReader(QXmlStreamReader &reader, QVariant &val); 0040 static bool timezoneReader(QXmlStreamReader &reader, QVariant &val); 0041 static bool attendeesReader(QXmlStreamReader &reader, QVariant &val); 0042 static bool occurrenceReader(QXmlStreamReader &reader, QVariant &val); 0043 static bool occurrencesReader(QXmlStreamReader &reader, QVariant &val); 0044 static bool recurrenceReader(QXmlStreamReader &reader, QVariant &val); 0045 static bool categoriesReader(QXmlStreamReader &reader, QVariant &val); 0046 static bool categoriesWriter(QXmlStreamWriter &writer, const QVariant &val); 0047 static bool attachmentsReader(QXmlStreamReader &reader, QVariant &val); 0048 0049 bool operator==(const EwsItemPrivate &other) const; 0050 0051 EwsItemType mType; 0052 static const Reader mStaticEwsXml; 0053 Reader mEwsXml; 0054 }; 0055 0056 static const QList<EwsItemPrivate::Reader::Item> ewsItemItems = { 0057 // Item fields 0058 {EwsItemFieldMimeContent, QStringLiteral("MimeContent"), &ewsXmlBase64Reader, &ewsXmlBase64Writer}, 0059 {EwsItemFieldItemId, QStringLiteral("ItemId"), &ewsXmlIdReader, &ewsXmlIdWriter}, 0060 {EwsItemFieldParentFolderId, QStringLiteral("ParentFolderId"), &ewsXmlIdReader, &ewsXmlIdWriter}, 0061 {EwsItemFieldItemClass, QStringLiteral("ItemClass"), &ewsXmlTextReader, &ewsXmlTextWriter}, 0062 {EwsItemFieldSubject, QStringLiteral("Subject"), &ewsXmlTextReader, &ewsXmlTextWriter}, 0063 {EwsItemFieldSensitivity, QStringLiteral("Sensitivity"), &ewsXmlSensitivityReader}, 0064 {EwsItemFieldBody, QStringLiteral("Body"), &EwsItemPrivate::bodyReader}, 0065 {EwsItemFieldAttachments, QStringLiteral("Attachments"), &EwsItemPrivate::attachmentsReader}, 0066 {EwsItemFieldDateTimeReceived, QStringLiteral("DateTimeReceived"), &ewsXmlDateTimeReader}, 0067 {EwsItemFieldSize, QStringLiteral("Size"), &ewsXmlUIntReader}, 0068 {EwsItemFieldCategories, QStringLiteral("Categories"), &EwsItemPrivate::categoriesReader, &EwsItemPrivate::categoriesWriter}, 0069 {EwsItemFieldImportance, QStringLiteral("Importance"), &ewsXmlImportanceReader}, 0070 {EwsItemFieldInReplyTo, QStringLiteral("InReplyTo"), &ewsXmlTextReader}, 0071 {EwsItemFieldIsDraft, QStringLiteral("IsDraft"), &ewsXmlBoolReader, &ewsXmlBoolWriter}, 0072 {EwsItemFieldIsFromMe, QStringLiteral("IsFromMe"), &ewsXmlBoolReader}, 0073 {EwsItemFieldInternetMessageHeaders, QStringLiteral("InternetMessageHeaders"), &EwsItemPrivate::messageHeadersReader}, 0074 {EwsItemFieldExtendedProperties, 0075 QStringLiteral("ExtendedProperty"), 0076 &EwsItemBasePrivate::extendedPropertyReader, 0077 &EwsItemBasePrivate::extendedPropertyWriter}, 0078 {EwsItemFieldHasAttachments, QStringLiteral("HasAttachments"), &ewsXmlBoolReader}, 0079 // Message fields 0080 {EwsItemFieldToRecipients, QStringLiteral("ToRecipients"), &EwsItemPrivate::recipientsReader}, 0081 {EwsItemFieldCcRecipients, QStringLiteral("CcRecipients"), &EwsItemPrivate::recipientsReader}, 0082 {EwsItemFieldBccRecipients, QStringLiteral("BccRecipients"), &EwsItemPrivate::recipientsReader}, 0083 {EwsItemFieldFrom, QStringLiteral("From"), &EwsItemPrivate::mailboxReader}, 0084 {EwsItemFieldInternetMessageId, QStringLiteral("InternetMessageId"), &ewsXmlTextReader}, 0085 {EwsItemFieldIsRead, QStringLiteral("IsRead"), &ewsXmlBoolReader, &ewsXmlBoolWriter}, 0086 {EwsItemFieldReferences, QStringLiteral("References"), &ewsXmlTextReader}, 0087 {EwsItemFieldReplyTo, QStringLiteral("ReplyTo"), &EwsItemPrivate::mailboxReader}, 0088 // CalendarItem fields 0089 {EwsItemFieldCalendarItemType, QStringLiteral("CalendarItemType"), &ewsXmlCalendarItemTypeReader}, 0090 {EwsItemFieldUID, QStringLiteral("UID"), &ewsXmlTextReader}, 0091 {EwsItemFieldCulture, QStringLiteral("Culture"), &ewsXmlTextReader}, 0092 {EwsItemFieldStartTimeZone, QStringLiteral("StartTimeZone"), &EwsItemPrivate::timezoneReader}, 0093 {EwsItemFieldOrganizer, QStringLiteral("Organizer"), &EwsItemPrivate::mailboxReader}, 0094 {EwsItemFieldRequiredAttendees, QStringLiteral("RequiredAttendees"), &EwsItemPrivate::attendeesReader}, 0095 {EwsItemFieldOptionalAttendees, QStringLiteral("OptionalAttendees"), &EwsItemPrivate::attendeesReader}, 0096 {EwsItemFieldResources, QStringLiteral("Resources"), &EwsItemPrivate::attendeesReader}, 0097 {EwsItemFieldStart, QStringLiteral("Start"), &ewsXmlDateTimeReader}, 0098 {EwsItemFieldEnd, QStringLiteral("End"), &ewsXmlDateTimeReader}, 0099 {EwsItemFieldRecurrenceId, QStringLiteral("RecurrenceId"), &ewsXmlDateTimeReader}, 0100 {EwsItemFieldIsAllDayEvent, QStringLiteral("IsAllDayEvent"), &ewsXmlBoolReader}, 0101 {EwsItemFieldLegacyFreeBusyStatus, QStringLiteral("LegacyFreeBusyStatus"), &ewsXmlLegacyFreeBusyStatusReader}, 0102 {EwsItemFieldMyResponseType, QStringLiteral("MyResponseType"), &ewsXmlResponseTypeReader}, 0103 {EwsItemFieldAppointmentSequenceNumber, QStringLiteral("AppointmentSequenceNumber"), &ewsXmlUIntReader}, 0104 {EwsItemFieldRecurrence, QStringLiteral("Recurrence"), &EwsItemPrivate::recurrenceReader}, 0105 {EwsItemFieldFirstOccurrence, QStringLiteral("FirstOccurrence"), &EwsItemPrivate::occurrenceReader}, 0106 {EwsItemFieldLastOccurrence, QStringLiteral("LastOccurrence"), &EwsItemPrivate::occurrenceReader}, 0107 {EwsItemFieldModifiedOccurrences, QStringLiteral("ModifiedOccurrences"), &EwsItemPrivate::occurrencesReader}, 0108 {EwsItemFieldDeletedOccurrences, QStringLiteral("DeletedOccurrences"), &EwsItemPrivate::occurrencesReader}, 0109 {EwsItemFieldTimeZone, QStringLiteral("TimeZone"), &ewsXmlTextReader}, 0110 {EwsItemFieldExchangePersonIdGuid, QStringLiteral("ExchangePersonIdGuid"), &ewsXmlTextReader}, 0111 {EwsItemFieldDoNotForwardMeeting, QStringLiteral("DoNotForwardMeeting"), &ewsXmlBoolReader}, 0112 }; 0113 0114 const EwsItemPrivate::Reader EwsItemPrivate::mStaticEwsXml(ewsItemItems); 0115 0116 EwsItemPrivate::EwsItemPrivate() 0117 : EwsItemBasePrivate() 0118 , mType(EwsItemTypeUnknown) 0119 , mEwsXml(mStaticEwsXml) 0120 { 0121 } 0122 0123 bool EwsItemPrivate::bodyReader(QXmlStreamReader &reader, QVariant &val) 0124 { 0125 QVariantList vl; 0126 auto bodyType = reader.attributes().value(QStringLiteral("BodyType")); 0127 if (bodyType.isNull()) { 0128 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - missing %2 attribute").arg(QStringLiteral("Body"), QStringLiteral("BodyType")); 0129 return false; 0130 } 0131 bool isHtml; 0132 if (bodyType == QLatin1StringView("HTML")) { 0133 isHtml = true; 0134 } else if (bodyType == QLatin1StringView("Text")) { 0135 isHtml = false; 0136 } else { 0137 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read Body element- unknown body type"); 0138 return false; 0139 } 0140 vl.append(reader.readElementText()); 0141 if (reader.error() != QXmlStreamReader::NoError) { 0142 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Failed to read %1 element - invalid content.").arg(QStringLiteral("Body")); 0143 return false; 0144 } 0145 vl.append(isHtml); 0146 val = vl; 0147 return true; 0148 } 0149 0150 bool EwsItemPrivate::messageHeadersReader(QXmlStreamReader &reader, QVariant &val) 0151 { 0152 EwsItem::HeaderMap map = val.value<EwsItem::HeaderMap>(); 0153 0154 while (reader.readNextStartElement()) { 0155 if (reader.namespaceUri() != ewsTypeNsUri) { 0156 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in InternetMessageHeaders element:") << reader.namespaceUri(); 0157 return false; 0158 } 0159 0160 if (reader.name() == QLatin1StringView("InternetMessageHeader")) { 0161 auto nameRef = reader.attributes().value(QStringLiteral("HeaderName")); 0162 if (nameRef.isNull()) { 0163 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Missing HeaderName attribute in InternetMessageHeader element."); 0164 return false; 0165 } 0166 QString name = nameRef.toString(); 0167 QString value = reader.readElementText(); 0168 map.insert(name, value); 0169 if (reader.error() != QXmlStreamReader::NoError) { 0170 qCWarning(EWSCLI_LOG) << QStringLiteral("Failed to read EWS request - invalid %1 element.").arg(QStringLiteral("InternetMessageHeader")); 0171 return false; 0172 } 0173 } 0174 } 0175 0176 val = QVariant::fromValue<EwsItem::HeaderMap>(map); 0177 0178 return true; 0179 } 0180 0181 bool EwsItemPrivate::recipientsReader(QXmlStreamReader &reader, QVariant &val) 0182 { 0183 EwsMailbox::List mboxList; 0184 0185 while (reader.readNextStartElement()) { 0186 if (reader.namespaceUri() != ewsTypeNsUri) { 0187 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in %1 element:").arg(reader.name().toString()) << reader.namespaceUri(); 0188 return false; 0189 } 0190 EwsMailbox mbox(reader); 0191 if (!mbox.isValid()) { 0192 return false; 0193 } 0194 mboxList.append(mbox); 0195 } 0196 0197 val = QVariant::fromValue<EwsMailbox::List>(mboxList); 0198 0199 return true; 0200 } 0201 0202 bool EwsItemPrivate::mailboxReader(QXmlStreamReader &reader, QVariant &val) 0203 { 0204 if (!reader.readNextStartElement()) { 0205 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Expected mailbox in %1 element:").arg(reader.name().toString()); 0206 return false; 0207 } 0208 0209 if (reader.namespaceUri() != ewsTypeNsUri) { 0210 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in %1 element:").arg(reader.name().toString()) << reader.namespaceUri(); 0211 reader.skipCurrentElement(); 0212 return false; 0213 } 0214 0215 EwsMailbox mbox(reader); 0216 if (!mbox.isValid()) { 0217 reader.skipCurrentElement(); 0218 return false; 0219 } 0220 0221 val = QVariant::fromValue<EwsMailbox>(mbox); 0222 0223 // Leave the element 0224 reader.skipCurrentElement(); 0225 0226 return true; 0227 } 0228 0229 bool EwsItemPrivate::timezoneReader(QXmlStreamReader &reader, QVariant &val) 0230 { 0231 // TODO: This only reads the timezone identifier. 0232 auto idRef = reader.attributes().value(QStringLiteral("Id")); 0233 if (idRef.isNull()) { 0234 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Error reading %1 element - missing %2 attribute").arg(reader.name().toString(), QStringLiteral("Id")); 0235 reader.skipCurrentElement(); 0236 return false; 0237 } else { 0238 reader.skipCurrentElement(); 0239 val = idRef.toString(); 0240 return true; 0241 } 0242 } 0243 0244 bool EwsItemPrivate::attendeesReader(QXmlStreamReader &reader, QVariant &val) 0245 { 0246 EwsAttendee::List attList; 0247 0248 while (reader.readNextStartElement()) { 0249 if (reader.namespaceUri() != ewsTypeNsUri) { 0250 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in %1 element:").arg(reader.name().toString()) << reader.namespaceUri(); 0251 return false; 0252 } 0253 EwsAttendee att(reader); 0254 if (!att.isValid()) { 0255 return false; 0256 } 0257 attList.append(att); 0258 } 0259 0260 val = QVariant::fromValue<EwsAttendee::List>(attList); 0261 0262 return true; 0263 } 0264 0265 bool EwsItemPrivate::occurrenceReader(QXmlStreamReader &reader, QVariant &val) 0266 { 0267 EwsOccurrence occ(reader); 0268 if (!occ.isValid()) { 0269 return false; 0270 } 0271 val = QVariant::fromValue<EwsOccurrence>(occ); 0272 return true; 0273 } 0274 0275 bool EwsItemPrivate::occurrencesReader(QXmlStreamReader &reader, QVariant &val) 0276 { 0277 EwsOccurrence::List occList; 0278 0279 while (reader.readNextStartElement()) { 0280 if (reader.namespaceUri() != ewsTypeNsUri) { 0281 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in %1 element:").arg(reader.name().toString()) << reader.namespaceUri(); 0282 return false; 0283 } 0284 EwsOccurrence occ(reader); 0285 if (!occ.isValid()) { 0286 return false; 0287 } 0288 occList.append(occ); 0289 } 0290 0291 val = QVariant::fromValue<EwsOccurrence::List>(occList); 0292 0293 return true; 0294 } 0295 0296 bool EwsItemPrivate::categoriesReader(QXmlStreamReader &reader, QVariant &val) 0297 { 0298 QStringList categories; 0299 0300 while (reader.readNextStartElement()) { 0301 if (reader.namespaceUri() != ewsTypeNsUri) { 0302 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in %1 element:").arg(reader.name().toString()) << reader.namespaceUri(); 0303 return false; 0304 } 0305 0306 if (reader.name() == QLatin1StringView("String")) { 0307 categories.append(reader.readElementText()); 0308 if (reader.error() != QXmlStreamReader::NoError) { 0309 qCWarning(EWSCLI_LOG) << QStringLiteral("Failed to read EWS request - invalid %1 element.").arg(QStringLiteral("Categories/Value")); 0310 return false; 0311 } 0312 } 0313 } 0314 0315 val = categories; 0316 0317 return true; 0318 } 0319 0320 bool EwsItemPrivate::categoriesWriter(QXmlStreamWriter &writer, const QVariant &val) 0321 { 0322 const QStringList categories = val.toStringList(); 0323 0324 for (const QString &cat : categories) { 0325 writer.writeTextElement(ewsTypeNsUri, QStringLiteral("String"), cat); 0326 } 0327 0328 return true; 0329 } 0330 0331 bool EwsItemPrivate::recurrenceReader(QXmlStreamReader &reader, QVariant &val) 0332 { 0333 EwsRecurrence recurrence(reader); 0334 val = QVariant::fromValue<EwsRecurrence>(recurrence); 0335 return true; 0336 } 0337 0338 bool EwsItemPrivate::attachmentsReader(QXmlStreamReader &reader, QVariant &val) 0339 { 0340 EwsAttachment::List attList; 0341 0342 while (reader.readNextStartElement()) { 0343 if (reader.namespaceUri() != ewsTypeNsUri) { 0344 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unexpected namespace in %1 element:").arg(reader.name().toString()) << reader.namespaceUri(); 0345 return false; 0346 } 0347 EwsAttachment att(reader); 0348 if (!att.isValid()) { 0349 return false; 0350 } 0351 attList.append(att); 0352 } 0353 0354 val = QVariant::fromValue<EwsAttachment::List>(attList); 0355 0356 return true; 0357 } 0358 0359 bool EwsItemPrivate::operator==(const EwsItemPrivate &other) const 0360 { 0361 if (!EwsItemBasePrivate::operator==(other)) { 0362 return false; 0363 } 0364 return mType == other.mType; 0365 } 0366 0367 EwsItem::EwsItem() 0368 : EwsItemBase(QSharedDataPointer<EwsItemBasePrivate>(new EwsItemPrivate())) 0369 { 0370 } 0371 0372 EwsItem::EwsItem(QXmlStreamReader &reader) 0373 : EwsItemBase(QSharedDataPointer<EwsItemBasePrivate>(new EwsItemPrivate())) 0374 { 0375 qRegisterMetaType<EwsItem::HeaderMap>(); 0376 qRegisterMetaType<EwsMailbox>(); 0377 qRegisterMetaType<EwsMailbox::List>(); 0378 qRegisterMetaType<EwsAttendee>(); 0379 qRegisterMetaType<EwsAttendee::List>(); 0380 qRegisterMetaType<EwsRecurrence>(); 0381 qRegisterMetaType<EwsOccurrence>(); 0382 qRegisterMetaType<EwsOccurrence::List>(); 0383 0384 auto d = reinterpret_cast<EwsItemPrivate *>(this->d.data()); 0385 0386 // Check what item type are we 0387 const auto elmName = reader.name(); 0388 if (elmName == QLatin1StringView("Item")) { 0389 d->mType = EwsItemTypeItem; 0390 const auto subtype = reader.attributes().value(QStringLiteral("xsi:type")); 0391 if (!subtype.isEmpty()) { 0392 auto tokens = subtype.split(QLatin1Char(':')); 0393 const auto type = tokens.size() == 1 ? tokens[0] : tokens[1]; 0394 if (type == QLatin1StringView("AbchPersonItemType")) { 0395 d->mType = EwsItemTypeAbchPerson; 0396 } 0397 } 0398 } else if (elmName == QLatin1StringView("Message")) { 0399 d->mType = EwsItemTypeMessage; 0400 } else if (elmName == QLatin1StringView("CalendarItem")) { 0401 d->mType = EwsItemTypeCalendarItem; 0402 } else if (elmName == QLatin1StringView("Contact")) { 0403 d->mType = EwsItemTypeContact; 0404 } else if (elmName == QLatin1StringView("DistributionList")) { 0405 d->mType = EwsItemTypeDistributionList; 0406 } else if (elmName == QLatin1StringView("MeetingMessage")) { 0407 d->mType = EwsItemTypeMeetingMessage; 0408 } else if (elmName == QLatin1StringView("MeetingRequest")) { 0409 d->mType = EwsItemTypeMeetingRequest; 0410 } else if (elmName == QLatin1StringView("MeetingResponse")) { 0411 d->mType = EwsItemTypeMeetingResponse; 0412 } else if (elmName == QLatin1StringView("MeetingCancellation")) { 0413 d->mType = EwsItemTypeMeetingCancellation; 0414 } else if (elmName == QLatin1StringView("PostItem")) { 0415 d->mType = EwsItemTypePostItem; 0416 } else if (elmName == QLatin1StringView("Task")) { 0417 d->mType = EwsItemTypeTask; 0418 } else { 0419 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unknown item type: %1").arg(elmName); 0420 } 0421 0422 while (reader.readNextStartElement()) { 0423 if (reader.namespaceUri() != ewsTypeNsUri) { 0424 qCWarningNC(EWSCLI_LOG) << "Unexpected namespace in Item element:" << reader.namespaceUri(); 0425 return; 0426 } 0427 0428 if (!readBaseItemElement(reader)) { 0429 qCWarningNC(EWSCLI_LOG) << QStringLiteral("Invalid Item child: %1").arg(reader.qualifiedName().toString()); 0430 return; 0431 } 0432 } 0433 d->mValid = true; 0434 } 0435 0436 EwsItem::EwsItem(const EwsItem &other) 0437 : EwsItemBase(other.d) 0438 { 0439 } 0440 0441 EwsItem::EwsItem(EwsItem &&other) 0442 : EwsItemBase(other.d) 0443 { 0444 } 0445 0446 EwsItem::~EwsItem() 0447 { 0448 } 0449 0450 EwsItem &EwsItem::operator=(const EwsItem &other) 0451 { 0452 d = other.d; 0453 return *this; 0454 } 0455 0456 EwsItem &EwsItem::operator=(EwsItem &&other) 0457 { 0458 d = std::move(other.d); 0459 return *this; 0460 } 0461 0462 EwsItemType EwsItem::type() const 0463 { 0464 const auto d = reinterpret_cast<const EwsItemPrivate *>(this->d.data()); 0465 return d->mType; 0466 } 0467 0468 void EwsItem::setType(EwsItemType type) 0469 { 0470 D_PTR 0471 d->mType = type; 0472 d->mValid = true; 0473 } 0474 0475 EwsItemType EwsItem::internalType() const 0476 { 0477 D_CPTR 0478 0479 EwsItemType type = d->mType; 0480 switch (type) { 0481 case EwsItemTypeMeetingMessage: 0482 case EwsItemTypeMeetingRequest: 0483 case EwsItemTypeMeetingResponse: 0484 case EwsItemTypeMeetingCancellation: 0485 type = EwsItemTypeMessage; 0486 break; 0487 case EwsItemTypeDistributionList: 0488 type = EwsItemTypeContact; 0489 break; 0490 default: 0491 break; 0492 } 0493 return type; 0494 } 0495 0496 bool EwsItem::readBaseItemElement(QXmlStreamReader &reader) 0497 { 0498 D_PTR 0499 0500 if (!d->mEwsXml.readItem(reader, QStringLiteral("Item"), ewsTypeNsUri)) { 0501 return false; 0502 } 0503 0504 d->mFields = d->mEwsXml.values(); 0505 0506 // The body item is special as it hold two values in one. Need to separate them into their 0507 // proper places. 0508 if (d->mFields.contains(EwsItemFieldBody)) { 0509 QVariantList vl = d->mFields[EwsItemFieldBody].value<QVariantList>(); 0510 QVariantList::const_iterator it = vl.cbegin(); 0511 d->mFields[EwsItemFieldBody] = *it++; 0512 d->mFields[EwsItemFieldBodyIsHtml] = *it; 0513 } 0514 return true; 0515 } 0516 0517 bool EwsItem::write(QXmlStreamWriter &writer) const 0518 { 0519 D_CPTR 0520 0521 writer.writeStartElement(ewsTypeNsUri, ewsItemTypeNames[d->mType]); 0522 0523 bool status = d->mEwsXml.writeItems(writer, ewsItemTypeNames[d->mType], ewsTypeNsUri, d->mFields); 0524 0525 writer.writeEndElement(); 0526 0527 return status; 0528 } 0529 0530 bool EwsItem::operator==(const EwsItem &other) const 0531 { 0532 return *d == *other.d; 0533 }