Example #1
0
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);
    }