Akonadi::Item KolabHelpers::translateFromImap(Kolab::FolderType folderType, const Akonadi::Item &imapItem, bool &ok) { //Avoid trying to convert imap messages if (folderType == Kolab::MailType) { return imapItem; } //No payload, probably a flag change or alike, we just pass it through if (!imapItem.hasPayload()) { return imapItem; } if (!imapItem.hasPayload<KMime::Message::Ptr>()) { qCWarning(KOLABRESOURCE_LOG) << "Payload is not a MessagePtr!"; Q_ASSERT(false); ok = false; return imapItem; } const KMime::Message::Ptr payload = imapItem.payload<KMime::Message::Ptr>(); const Kolab::KolabObjectReader reader(payload); if (checkForErrors(imapItem)) { ok = true; //We return an error object so the sync keeps working, and we can clean up the mess by simply deleting the object in the application. return getErrorItem(folderType, imapItem.remoteId()); } switch (reader.getType()) { case Kolab::EventObject: case Kolab::TodoObject: case Kolab::JournalObject: { const KCalCore::Incidence::Ptr incidencePtr = reader.getIncidence(); if (!incidencePtr) { qCWarning(KOLABRESOURCE_LOG) << "Failed to read incidence."; ok = false; return Akonadi::Item(); } Akonadi::Item newItem(incidencePtr->mimeType()); newItem.setPayload(incidencePtr); newItem.setRemoteId(imapItem.remoteId()); newItem.setGid(incidencePtr->instanceIdentifier()); return newItem; } break; case Kolab::NoteObject: { const KMime::Message::Ptr note = reader.getNote(); if (!note) { qCWarning(KOLABRESOURCE_LOG) << "Failed to read note."; ok = false; return Akonadi::Item(); } Akonadi::Item newItem(QStringLiteral("text/x-vnd.akonadi.note")); newItem.setPayload(note); newItem.setRemoteId(imapItem.remoteId()); const Akonadi::NoteUtils::NoteMessageWrapper wrapper(note); newItem.setGid(wrapper.uid()); return newItem; } break; case Kolab::ContactObject: { Akonadi::Item newItem(KContacts::Addressee::mimeType()); newItem.setPayload(reader.getContact()); newItem.setRemoteId(imapItem.remoteId()); newItem.setGid(reader.getContact().uid()); return newItem; } break; case Kolab::DistlistObject: { KContacts::ContactGroup contactGroup = reader.getDistlist(); QList<KContacts::ContactGroup::ContactReference> toAdd; for (uint index = 0; index < contactGroup.contactReferenceCount(); ++index) { const KContacts::ContactGroup::ContactReference &reference = contactGroup.contactReference(index); KContacts::ContactGroup::ContactReference ref; ref.setGid(reference.uid()); //libkolab set a gid with setUid() toAdd << ref; } contactGroup.removeAllContactReferences(); foreach (const KContacts::ContactGroup::ContactReference &ref, toAdd) { contactGroup.append(ref); } Akonadi::Item newItem(KContacts::ContactGroup::mimeType()); newItem.setPayload(contactGroup); newItem.setRemoteId(imapItem.remoteId()); newItem.setGid(contactGroup.id()); return newItem; } break; default: qCWarning(KOLABRESOURCE_LOG) << "Object type not handled"; ok = false; break; }
void IncidenceChanger::Private::onCollectionsLoaded(KJob *job) { Q_ASSERT(!mPendingCreations.isEmpty()); if (job->error() != 0 || !m_collectionFetchJob) { qCritical() << "Error loading collections:" << job->errorString(); return; } Q_ASSERT(job == m_collectionFetchJob); Akonadi::Collection::List allCollections; foreach (const Akonadi::Collection &collection, m_collectionFetchJob->collections()) { if (collection.rights() & Akonadi::Collection::CanCreateItem) { allCollections << collection; } } m_collectionFetchJob = Q_NULLPTR; bool canceled = false; // These two will never be true, maybe even assert bool noAcl = false; bool invalidCollection = false; Collection collectionToUse; foreach (const Change::Ptr &change, mPendingCreations) { mPendingCreations.removeAll(change); if (canceled) { change->resultCode = ResultCodeUserCanceled; continue; } if (noAcl) { change->resultCode = ResultCodePermissions; continue; } if (invalidCollection) { change->resultCode = ResultCodeInvalidUserCollection; continue; } if (collectionToUse.isValid()) { // We don't show the dialog multiple times step2CreateIncidence(change, collectionToUse); continue; } KCalCore::Incidence::Ptr incidence = CalendarUtils::incidence(change->newItem); Collection::List candidateCollections = collectionsForMimeType(incidence->mimeType(), allCollections); if (candidateCollections.count() == 1 && candidateCollections.first().isValid()) { // We only have 1 writable collection, don't bother the user with a dialog collectionToUse = candidateCollections.first(); qCDebug(AKONADICALENDAR_LOG) << "Only one collection exists, will not show collection dialog: " << collectionToUse.displayName(); step2CreateIncidence(change, collectionToUse); continue; } // Lets ask the user which collection to use: int dialogCode; QWidget *parent = change->parentWidget; const QStringList mimeTypes(incidence->mimeType()); collectionToUse = CalendarUtils::selectCollection(parent, /*by-ref*/dialogCode, mimeTypes, mDefaultCollection); if (dialogCode != QDialog::Accepted) { qCDebug(AKONADICALENDAR_LOG) << "User canceled collection choosing"; change->resultCode = ResultCodeUserCanceled; canceled = true; cancelTransaction(); continue; } if (collectionToUse.isValid() && !hasRights(collectionToUse, ChangeTypeCreate)) { qCWarning(AKONADICALENDAR_LOG) << "No ACLs for incidence creation"; const QString errorMessage = showErrorDialog(ResultCodePermissions, parent); change->resultCode = ResultCodePermissions; change->errorString = errorMessage; noAcl = true; cancelTransaction(); continue; } // TODO: add unit test for these two situations after reviewing API if (!collectionToUse.isValid()) { qCritical() << "Invalid collection selected. Can't create incidence."; change->resultCode = ResultCodeInvalidUserCollection; const QString errorString = showErrorDialog(ResultCodeInvalidUserCollection, parent); change->errorString = errorString; invalidCollection = true; cancelTransaction(); continue; } step2CreateIncidence(change, collectionToUse); }