diff -r 000000000000 -r 876b1a06bc25 src/versit/qversitcontactexporter_p.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/versit/qversitcontactexporter_p.cpp Wed Aug 25 15:49:42 2010 +0300 @@ -0,0 +1,838 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qversitcontactexporter.h" +#include "qversitcontactexporter_p.h" +#include "qversitdefs_p.h" +#include "versitutils_p.h" +#include "qmobilityglobal.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +QTM_USE_NAMESPACE + +/*! + * Constructor. + */ +QVersitContactExporterPrivate::QVersitContactExporterPrivate() : + mDetailHandler(NULL), + mDetailHandler2(NULL), + mDetailHandlerVersion(0), + mDefaultResourceHandler(new QVersitDefaultResourceHandler), + mResourceHandler(mDefaultResourceHandler), + mVersitType(QVersitDocument::InvalidType) +{ + // Detail mappings + int versitPropertyCount = + sizeof(versitContactDetailMappings)/sizeof(VersitContactDetailMapping); + for (int i=0; i < versitPropertyCount; i++) { + mPropertyMappings.insert( + QLatin1String(versitContactDetailMappings[i].contactDetailDefinitionName), + QLatin1String(versitContactDetailMappings[i].versitPropertyName)); + } + + // Contexts mappings + int contextCount = sizeof(versitContextMappings)/sizeof(VersitMapping); + for (int i=0; i < contextCount; i++) { + mParameterMappings.insert( + QLatin1String(versitContextMappings[i].contactString), + QLatin1String(versitContextMappings[i].versitString)); + } + + // Subtypes mappings + int subTypeCount = sizeof(versitSubTypeMappings)/sizeof(VersitMapping); + for (int i=0; i < subTypeCount; i++) { + mParameterMappings.insert( + QLatin1String(versitSubTypeMappings[i].contactString), + QLatin1String(versitSubTypeMappings[i].versitString)); + } +} + +/*! + * Destructor. + */ +QVersitContactExporterPrivate::~QVersitContactExporterPrivate() +{ + delete mDefaultResourceHandler; +} + + +/*! + * Export QT Contact into Versit Document. + */ +bool QVersitContactExporterPrivate::exportContact( + const QContact& contact, + QVersitDocument& document, + QVersitContactExporter::Error* error) +{ + mVersitType = document.type(); + QList allDetails = contact.details(); + if (allDetails.isEmpty()) { + *error = QVersitContactExporter::EmptyContactError; + return false; + } + for (int i = 0; i < allDetails.size(); i++) { + QContactDetail detail = allDetails.at(i); + + // If the custom detail handler handles it, we don't have to. + if (mDetailHandler + && mDetailHandler->preProcessDetail(contact, detail, &document)) + continue; + + QList removedProperties; + QList generatedProperties; + QSet processedFields; + + if (detail.definitionName() == QContactName::DefinitionName) { + encodeName(detail, document, &removedProperties, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactPhoneNumber::DefinitionName) { + encodePhoneNumber(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactEmailAddress::DefinitionName) { + encodeEmail(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactAddress::DefinitionName) { + encodeAddress(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactGuid::DefinitionName) { + encodeUid(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactUrl::DefinitionName) { + encodeUrl(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactTimestamp::DefinitionName) { + encodeRev(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactBirthday::DefinitionName) { + encodeBirthDay(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactGeoLocation::DefinitionName) { + encodeGeoLocation(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactNote::DefinitionName) { + encodeNote(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactOrganization::DefinitionName) { + encodeOrganization(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactRingtone::DefinitionName) { + encodeRingtone(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactThumbnail::DefinitionName) { + encodeThumbnail(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactAvatar::DefinitionName){ + encodeAvatar(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactAnniversary::DefinitionName) { + encodeAnniversary(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactNickname::DefinitionName) { + encodeNickname(detail, document, &removedProperties, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactTag::DefinitionName) { + encodeTag(detail, document, &removedProperties, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactGender::DefinitionName) { + encodeGender(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactOnlineAccount::DefinitionName) { + encodeOnlineAccount(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactFamily::DefinitionName) { + encodeFamily(detail, &generatedProperties, &processedFields); + } else if (detail.definitionName() == QContactDisplayLabel::DefinitionName) { + encodeDisplayLabel(detail, document, &removedProperties, &generatedProperties, &processedFields); + } + + if (mDetailHandler2 && mDetailHandlerVersion > 1) { + mDetailHandler2->detailProcessed(contact, detail, processedFields, document, + &removedProperties, &generatedProperties); + } + + foreach(const QVersitProperty& property, removedProperties) { + document.removeProperty(property); + } + foreach(const QVersitProperty& property, generatedProperties) { + document.addProperty(property); + } + + if (mDetailHandler && mDetailHandlerVersion == 1) { + mDetailHandler->postProcessDetail(contact, detail, !processedFields.isEmpty(), &document); + } + } + + if (mDetailHandler2 && mDetailHandlerVersion > 1) { + mDetailHandler2->contactProcessed(contact, &document); + } + + // Search through the document for FN or N properties. This will find it even if it was added + // by a detail handler. + if (!documentContainsName(document)) { + *error = QVersitContactExporter::NoNameError; + return false; + } + return true; +} + +/*! + * Returns true if and only if \a document has a "FN" or "N" property. + */ +bool QVersitContactExporterPrivate::documentContainsName(const QVersitDocument &document) +{ + foreach (const QVersitProperty& property, document.properties()) { + const QString& name = property.name(); + if (name == QLatin1String("FN") || name == QLatin1String("N")) + return true; + } + return false; +} + +/*! + * Encode Contact Name Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeName( + const QContactDetail& detail, + const QVersitDocument& document, + QList* removedProperties, + QList* generatedProperties, + QSet* processedFields) +{ + QContactName contactName = static_cast(detail); + if (!contactName.lastName().isEmpty() + || !contactName.firstName().isEmpty() + || !contactName.middleName().isEmpty() + || !contactName.prefix().isEmpty() + || !contactName.suffix().isEmpty()) { + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + property.setValue(QStringList() + << contactName.lastName() + << contactName.firstName() + << contactName.middleName() + << contactName.prefix() + << contactName.suffix()); + property.setValueType(QVersitProperty::CompoundType); + *generatedProperties << property; + } + + // Generate an FN field if none is already there + // Don't override previously exported FN properties (eg. exported by a DisplayLabel detail) + QVersitProperty fnProperty = takeProperty(document, QLatin1String("FN"), removedProperties); + if (fnProperty.value().isEmpty()) { + fnProperty.setName(QLatin1String("FN")); + if (!contactName.customLabel().isEmpty()) { + fnProperty.setValue(contactName.customLabel()); + } else if (!contactName.firstName().isEmpty()) { + if (!contactName.lastName().isEmpty()) { + fnProperty.setValue(QString::fromAscii("%1 %2").arg(contactName.firstName(), + contactName.lastName())); + } else { + fnProperty.setValue(contactName.firstName()); + } + } else if (!contactName.lastName().isEmpty()) { + fnProperty.setValue(contactName.lastName()); + } + } + + *generatedProperties << fnProperty; + *processedFields << QContactName::FieldLastName + << QContactName::FieldFirstName + << QContactName::FieldMiddleName + << QContactName::FieldPrefix + << QContactName::FieldSuffix + << QContactName::FieldCustomLabel; +} + +/*! + * Encode Phone Number Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodePhoneNumber( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactPhoneNumber phoneNumber = static_cast(detail); + QStringList subTypes = phoneNumber.subTypes(); + QVersitProperty property; + if (subTypes.contains(QContactPhoneNumber::SubTypeAssistant)) + property.setName(QLatin1String("X-ASSISTANT-TEL")); + else + property.setName(QLatin1String("TEL")); + encodeParameters(property, phoneNumber.contexts(), subTypes); + property.setValue(phoneNumber.number()); + *generatedProperties << property; + *processedFields << QContactPhoneNumber::FieldContext + << QContactPhoneNumber::FieldSubTypes + << QContactPhoneNumber::FieldNumber; +} + +/*! + * Encode Email Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeEmail( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactEmailAddress emailAddress = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + encodeParameters(property, emailAddress.contexts()); + property.setValue(emailAddress.emailAddress()); + *generatedProperties << property; + *processedFields << QContactEmailAddress::FieldContext + << QContactEmailAddress::FieldEmailAddress; +} + +/*! + * Encode Address Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeAddress( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactAddress address = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + encodeParameters(property, address.contexts(), address.subTypes()); + property.setValue(QStringList() + << address.postOfficeBox() + << QString() // Leave out the extended address field + << address.street() + << address.locality() + << address.region() + << address.postcode() + << address.country()); + property.setValueType(QVersitProperty::CompoundType); + *generatedProperties << property; + *processedFields << QContactAddress::FieldContext + << QContactAddress::FieldSubTypes + << QContactAddress::FieldPostOfficeBox + << QContactAddress::FieldStreet + << QContactAddress::FieldLocality + << QContactAddress::FieldRegion + << QContactAddress::FieldPostcode + << QContactAddress::FieldCountry; +} + +/*! + * Encode URL Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeUrl( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactUrl contactUrl = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + encodeParameters(property, contactUrl.contexts()); + // The vCard specifications do not define any TYPEs for URL property. + // No need to try to convert the subtypes to TYPEs. + property.setValue(contactUrl.url()); + *generatedProperties << property; + *processedFields << QContactUrl::FieldContext + << QContactUrl::FieldUrl; +} + +/*! + * Encode Uid Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeUid( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactGuid uid = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + property.setValue(uid.guid()); + *generatedProperties << property; + *processedFields << QContactGuid::FieldGuid; +} + +/*! + * Encode REV Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeRev( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactTimestamp rev = static_cast(detail); + QString value; + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + + if ( rev.lastModified().toString(Qt::ISODate).size() ) { + if ( rev.lastModified().timeSpec() == Qt::UTC ) { + value = rev.lastModified().toString(Qt::ISODate) + QLatin1Char('Z'); + } + else { + value = rev.lastModified().toString(Qt::ISODate); + } + property.setValue(value); + *generatedProperties << property; + *processedFields << QContactTimestamp::FieldModificationTimestamp; + } else if ( rev.created().toString(Qt::ISODate).size()) { + if ( rev.created().timeSpec() == Qt::UTC ) { + value = rev.created().toString(Qt::ISODate) + QLatin1Char('Z'); + } + else { + value = rev.created().toString(Qt::ISODate); + } + property.setValue(value); + *generatedProperties << property; + *processedFields << QContactTimestamp::FieldCreationTimestamp; + } +} + +/*! + * Encode BirthDay Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeBirthDay( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactBirthday bday = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + QString value = bday.date().toString(Qt::ISODate); + property.setValue(value); + *generatedProperties << property; + *processedFields << QContactBirthday::FieldBirthday; +} + +/*! + * Encode Comment i.e. Note Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeNote( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactNote contactNote = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + property.setValue(contactNote.note()); + *generatedProperties << property; + *processedFields << QContactNote::FieldNote; +} + +/*! + * Encode Geo Prpoperties Field Information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeGeoLocation( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactGeoLocation geoLocation = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + property.setValue(QStringList() << QString::number(geoLocation.longitude()) + << QString::number(geoLocation.latitude())); + property.setValueType(QVersitProperty::CompoundType); + *generatedProperties << property; + *processedFields << QContactGeoLocation::FieldLongitude + << QContactGeoLocation::FieldLatitude; +} + +/*! + * Encode organization properties to the versit document + */ +void QVersitContactExporterPrivate::encodeOrganization( + const QContactDetail& detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactOrganization organization = static_cast(detail); + if (organization.title().length() > 0) { + QVersitProperty property; + property.setName(QLatin1String("TITLE")); + property.setValue(organization.title()); + *generatedProperties << property; + *processedFields << QContactOrganization::FieldTitle; + } + if (organization.name().length() > 0 || organization.department().size() > 0) { + QVersitProperty property; + property.setName(QLatin1String("ORG")); + QStringList values(organization.name()); + values.append(organization.department()); + property.setValue(values); + property.setValueType(QVersitProperty::CompoundType); + *generatedProperties << property; + *processedFields << QContactOrganization::FieldName + << QContactOrganization::FieldDepartment; + } + if (organization.logoUrl().isValid()) { + QVersitProperty property; + if (encodeContentFromFile(organization.logoUrl().toString(), property)) { + property.setName(QLatin1String("LOGO")); + *generatedProperties << property; + *processedFields << QContactOrganization::FieldLogoUrl; + } + } + if (organization.assistantName().length() > 0) { + QVersitProperty property; + property.setName(QLatin1String("X-ASSISTANT")); + property.setValue(organization.assistantName()); + *generatedProperties << property; + *processedFields << QContactOrganization::FieldAssistantName; + } + + if (organization.role().length() > 0) { + QVersitProperty property; + property.setName(QLatin1String("ROLE")); + property.setValue(organization.role()); + *generatedProperties << property; + *processedFields << QContactOrganization::FieldRole; + } +} + +void QVersitContactExporterPrivate::encodeRingtone( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactRingtone ringtone = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + if (encodeContentFromFile(ringtone.audioRingtoneUrl().toLocalFile(), property)) { + *generatedProperties << property; + *processedFields << QContactRingtone::FieldAudioRingtoneUrl; + } +} + +/*! + * Encode thumbnail content into the Versit Document + */ +void QVersitContactExporterPrivate::encodeThumbnail( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactThumbnail contactThumbnail = static_cast(detail); + QVersitProperty property; + property.setName(QLatin1String("PHOTO")); + QImage image = contactThumbnail.thumbnail(); + if (image.isNull()) + return; + QByteArray imageData; + QBuffer buffer(&imageData); + buffer.open(QIODevice::WriteOnly); + // Always store a pixmap as a PNG. + if (!image.save(&buffer, "PNG")) + return; + property.setValue(imageData); + property.insertParameter(QLatin1String("TYPE"), QLatin1String("PNG")); + *generatedProperties << property; + *processedFields << QContactThumbnail::FieldThumbnail; +} + +/*! + * Encode avatar URIs into the Versit Document + */ +void QVersitContactExporterPrivate::encodeAvatar( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QVersitProperty property; + property.setName(QLatin1String("PHOTO")); + QContactAvatar contactAvatar = static_cast(detail); + QUrl imageUrl(contactAvatar.imageUrl()); + // XXX: fix up this mess: checking the scheme here and in encodeContentFromFile, + // organisation logo and ringtone are QStrings but avatar is a QUrl + if (!imageUrl.scheme().isEmpty() && !imageUrl.host().isEmpty()) { + property.insertParameter(QLatin1String("VALUE"), QLatin1String("URL")); + property.setValue(imageUrl.toString()); + *generatedProperties << property; + *processedFields << QContactAvatar::FieldImageUrl; + } else { + if (encodeContentFromFile(contactAvatar.imageUrl().toString(), property)) { + *generatedProperties << property; + *processedFields << QContactAvatar::FieldImageUrl; + } + } +} + +/*! + * Encode gender property information into Versit Document + */ +void QVersitContactExporterPrivate::encodeGender( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactGender gender = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + property.setValue(gender.gender()); + *generatedProperties << property; + *processedFields << QContactGender::FieldGender; +} + +/*! + * Encodes nickname property information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeNickname( + const QContactDetail &detail, + const QVersitDocument& document, + QList* removedProperties, + QList* generatedProperties, + QSet* processedFields) +{ + QContactNickname nicknameDetail = static_cast(detail); + QVersitProperty property = takeProperty(document, QLatin1String("X-NICKNAME"), removedProperties); + property.setName(QLatin1String("X-NICKNAME")); + QStringList value(property.variantValue().toStringList()); + value.append(nicknameDetail.nickname()); + property.setValue(value); + property.setValueType(QVersitProperty::ListType); + *generatedProperties << property; + *processedFields << QContactNickname::FieldNickname; +} + +/*! + * Encodes a contact tag into the Versit Document + */ +void QVersitContactExporterPrivate::encodeTag( + const QContactDetail &detail, + const QVersitDocument& document, + QList* removedProperties, + QList* generatedProperties, + QSet* processedFields) +{ + QContactTag tagDetail = static_cast(detail); + QVersitProperty property = takeProperty(document, QLatin1String("CATEGORIES"), removedProperties); + property.setName(QLatin1String("CATEGORIES")); + QStringList value(property.variantValue().toStringList()); + value.append(tagDetail.tag()); + property.setValue(value); + property.setValueType(QVersitProperty::ListType); + *generatedProperties << property; + *processedFields << QContactTag::FieldTag; +} + +/*! + * Encode anniversary information into Versit Document + */ +void QVersitContactExporterPrivate::encodeAnniversary( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactAnniversary anniversary = static_cast(detail); + QVersitProperty property; + property.setName(mPropertyMappings.value(detail.definitionName())); + property.setValue(anniversary.originalDate().toString(Qt::ISODate)); + *generatedProperties << property; + *processedFields << QContactAnniversary::FieldOriginalDate; +} + +/*! + * Encode online account information into the Versit Document + */ +void QVersitContactExporterPrivate::encodeOnlineAccount( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactOnlineAccount onlineAccount = static_cast(detail); + QStringList subTypes = onlineAccount.subTypes(); + + if (subTypes.contains(QContactOnlineAccount::SubTypeSip) || + subTypes.contains(QContactOnlineAccount::SubTypeSipVoip) || + subTypes.contains(QContactOnlineAccount::SubTypeVideoShare) || + subTypes.contains(QContactOnlineAccount::SubTypeImpp)) { + QVersitProperty property; + encodeParameters(property, onlineAccount.contexts(), subTypes); + QString name(QLatin1String("X-SIP")); + if (subTypes.contains(QContactOnlineAccount::SubTypeImpp)) + name = QLatin1String("X-IMPP"); + property.setName(name); + property.setValue(onlineAccount.accountUri()); + *generatedProperties << property; + *processedFields << QContactOnlineAccount::FieldSubTypes + << QContactOnlineAccount::FieldAccountUri; + } +} + +/*! + * Encode family versit property if its supported in Versit Document + */ +void QVersitContactExporterPrivate::encodeFamily( + const QContactDetail &detail, + QList* generatedProperties, + QSet* processedFields) +{ + QContactFamily family = static_cast(detail); + + if (family.spouse().size()) { + QVersitProperty property; + property.setName(QLatin1String("X-SPOUSE")); + property.setValue(family.spouse()); + *generatedProperties << property; + *processedFields << QContactFamily::FieldSpouse; + } + + if (family.children().size()) { + QVersitProperty property; + property.setName(QLatin1String("X-CHILDREN")); + property.setValue(family.children()); + property.setValueType(QVersitProperty::ListType); + *generatedProperties << property; + *processedFields << QContactFamily::FieldChildren; + } +} + + +/*! + * Encode family versit property if its supported in Versit Document + */ +void QVersitContactExporterPrivate::encodeDisplayLabel( + const QContactDetail &detail, + const QVersitDocument& document, + QList* removedProperties, + QList* generatedProperties, + QSet* processedFields) +{ + // Override any previous FN property + QVersitProperty property = takeProperty(document, QLatin1String("FN"), removedProperties); + property.setName(mPropertyMappings.value(detail.definitionName())); + QContactDisplayLabel displayLabel = static_cast(detail); + if (!displayLabel.label().isEmpty()) { + property.setValue(displayLabel.label()); + *generatedProperties << property; + *processedFields << QContactDisplayLabel::FieldLabel; + } +} + +/*! + * Finds a property in the \a document with the given \a propertyName, removes it and returns it. + */ +QVersitProperty QVersitContactExporterPrivate::takeProperty(const QVersitDocument& document, + const QString& propertyName, + QList* toBeRemoved) { + foreach (const QVersitProperty& currentProperty, document.properties()) { + if (currentProperty.name() == propertyName) { + *toBeRemoved << currentProperty; + return currentProperty; + } + } + return QVersitProperty(); +} + +/*! + * Check if \a resourceIdentifier represents a valid remote resource + */ +bool QVersitContactExporterPrivate::isValidRemoteUrl( + const QString& resourceIdentifier) +{ + QUrl remoteResource(resourceIdentifier); + if ((!remoteResource.scheme().isEmpty() && + !remoteResource.host().isEmpty()) || + resourceIdentifier.contains(QLatin1String("www."), Qt::CaseInsensitive)) + return true; + return false; +} + +/*! + * Encode parameters to \a property + */ +void QVersitContactExporterPrivate::encodeParameters( + QVersitProperty& property, + const QStringList& contexts, + const QStringList& subTypes) +{ + QStringList parameterList(contexts); // Contexts should be encoded first + parameterList << subTypes; + while (!parameterList.isEmpty()) { + QString value = parameterList.takeLast(); + QString mappedValue = mParameterMappings.value(value); + if (mappedValue.length() > 0) { + // QVersitProperty::addParameter inserts into beginning. + // This is why the last value is taken from the list + property.insertParameter(QLatin1String("TYPE"),mappedValue); + } + } +} + +/*! + * Encode embedded content from the given \a resourcePath into \a property. + */ +bool QVersitContactExporterPrivate::encodeContentFromFile(const QString& resourcePath, + QVersitProperty& property) +{ + bool encodeContent = false; + QVariant value; + QByteArray imageData; + QString mimeType; + if (isValidRemoteUrl( resourcePath )) { + encodeContent = true; + value.setValue(resourcePath); + property.insertParameter(QLatin1String("VALUE"), QLatin1String("URL")); + } else if (mResourceHandler + && mResourceHandler->loadResource(resourcePath, &imageData, &mimeType)) { + value.setValue(imageData); + if (!mimeType.isEmpty()) { + // If mimeType is (eg.) "image/jpeg", set type parameter to "JPEG" + int slashIndex = mimeType.indexOf(QLatin1Char('/')); + if (slashIndex >= 0) + property.insertParameter(QLatin1String("TYPE"), + mimeType.remove(0, slashIndex+1).toUpper()); + } + encodeContent = true; + } else { + // The file doesn't exist. Don't encode the path to a local file. + } + property.setValue(value); + return encodeContent; +}