--- a/qtmobility/src/versit/qversitcontactexporter_p.cpp Fri Apr 16 15:51:22 2010 +0300
+++ b/qtmobility/src/versit/qversitcontactexporter_p.cpp Mon May 03 13:18:40 2010 +0300
@@ -65,6 +65,7 @@
#include <qcontactonlineaccount.h>
#include <qcontactfamily.h>
#include <qcontactdisplaylabel.h>
+#include <qcontactthumbnail.h>
#include <QUrl>
#include <QBuffer>
@@ -119,12 +120,17 @@
/*!
* Export QT Contact into Versit Document.
*/
-void QVersitContactExporterPrivate::exportContact(
+bool QVersitContactExporterPrivate::exportContact(
const QContact& contact,
- QVersitDocument& document)
+ QVersitDocument& document,
+ QVersitContactExporter::Error* error)
{
mVersitType = document.type();
QList<QContactDetail> allDetails = contact.details();
+ if (allDetails.isEmpty()) {
+ *error = QVersitContactExporter::EmptyContactError;
+ return false;
+ }
for (int i = 0; i < allDetails.size(); i++) {
QContactDetail detail = allDetails.at(i);
@@ -161,6 +167,12 @@
} else if (detail.definitionName() == QContactOrganization::DefinitionName) {
encodeOrganization(document, detail);
addProperty = false;
+ } else if (detail.definitionName() == QContactRingtone::DefinitionName) {
+ addProperty = encodeRingtone(property, detail);
+ } else if (detail.definitionName() == QContactThumbnail::DefinitionName) {
+ addProperty = encodeThumbnail(property, detail);
+ if (!addProperty)
+ unknown = true;
} else if (detail.definitionName() == QContactAvatar::DefinitionName){
addProperty = encodeAvatar(property, detail);
if (!addProperty)
@@ -170,6 +182,9 @@
} else if (detail.definitionName() == QContactNickname::DefinitionName) {
encodeNickname(document, detail);
addProperty = false;
+ } else if (detail.definitionName() == QContactTag::DefinitionName) {
+ encodeTag(document, detail);
+ addProperty = false;
} else if (detail.definitionName() == QContactGender::DefinitionName) {
encodeGender(property, detail);
} else if (detail.definitionName() == QContactOnlineAccount::DefinitionName) {
@@ -187,12 +202,34 @@
unknown = true;
}
- if (addProperty)
+ if (addProperty) {
document.addProperty(property);
+ }
if (mDetailHandler)
mDetailHandler->postProcessDetail(contact, detail, !unknown, &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;
}
/*!
@@ -203,12 +240,13 @@
const QContactDetail& detail)
{
QContactName contactName = static_cast<QContactName>(detail);
- property.setValue(QString::fromAscii("%1;%2;%3;%4;%5").arg(
- escape(contactName.lastName()),
- escape(contactName.firstName()),
- escape(contactName.middleName()),
- escape(contactName.prefix()),
- escape(contactName.suffix())));
+ property.setValue(QStringList()
+ << contactName.lastName()
+ << contactName.firstName()
+ << contactName.middleName()
+ << contactName.prefix()
+ << contactName.suffix());
+ property.setValueType(QVersitProperty::CompoundType);
}
/*!
@@ -220,7 +258,7 @@
{
QContactPhoneNumber phoneNumber = static_cast<QContactPhoneNumber>(detail);
encodeParameters(property, phoneNumber.contexts(), phoneNumber.subTypes());
- setEscapedValue(property,phoneNumber.number());
+ property.setValue(phoneNumber.number());
}
/*!
@@ -232,7 +270,7 @@
{
QContactEmailAddress emailAddress = static_cast<QContactEmailAddress>(detail);
encodeParameters(property, emailAddress.contexts());
- setEscapedValue(property,emailAddress.emailAddress());
+ property.setValue(emailAddress.emailAddress());
}
/*!
@@ -244,14 +282,15 @@
{
QContactAddress address = static_cast<QContactAddress>(detail);
encodeParameters(property, address.contexts(), address.subTypes());
- // Leave out the extended address field:
- property.setValue(QString::fromAscii("%1;;%2;%3;%4;%5;%6").arg(
- escape(address.postOfficeBox()),
- escape(address.street()),
- escape(address.locality()),
- escape(address.region()),
- escape(address.postcode()),
- escape(address.country())));
+ 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);
}
/*!
@@ -276,7 +315,7 @@
const QContactDetail& detail)
{
QContactGuid uid = static_cast<QContactGuid>(detail);
- setEscapedValue(property,uid.guid());
+ property.setValue(uid.guid());
}
/*!
@@ -334,7 +373,7 @@
const QContactDetail& detail)
{
QContactNote contactNote = static_cast<QContactNote>(detail);
- setEscapedValue(property,contactNote.note());
+ property.setValue(contactNote.note());
}
/*!
@@ -345,10 +384,9 @@
const QContactDetail& detail)
{
QContactGeoLocation geoLocation = static_cast<QContactGeoLocation>(detail);
- QString value =
- QString::number(geoLocation.longitude()) + QLatin1Char(',') +
- QString::number(geoLocation.latitude());
- property.setValue(value);
+ property.setValue(QStringList() << QString::number(geoLocation.longitude())
+ << QString::number(geoLocation.latitude()));
+ property.setValueType(QVersitProperty::CompoundType);
}
/*!
@@ -362,26 +400,22 @@
if (organization.title().length() > 0) {
QVersitProperty property;
property.setName(QLatin1String("TITLE"));
- setEscapedValue(property,organization.title());
+ property.setValue(organization.title());
document.addProperty(property);
}
if (organization.name().length() > 0 || organization.department().size() > 0) {
QVersitProperty property;
property.setName(QLatin1String("ORG"));
- QString value = escape(organization.name());
- QStringList departments(organization.department());
- if (departments.count() == 0)
- value += QLatin1Char(';');
- foreach (QString department, departments) {
- value += QLatin1Char(';');
- value += escape(department);
- }
- property.setValue(value);
+ QStringList values(organization.name());
+ values.append(organization.department());
+ property.setValue(values);
+ property.setValueType(QVersitProperty::CompoundType);
document.addProperty(property);
}
- if (organization.logo().length() > 0) {
+ if (organization.logoUrl().isValid()) {
QVersitProperty property;
- if (encodeContentFromFile(organization.logo(), property)) {
+ // XXX TODO: FIXME!
+ if (encodeContentFromFile(organization.logoUrl().toString(), property)) {
property.setName(QLatin1String("LOGO"));
document.addProperty(property);
}
@@ -389,43 +423,68 @@
if (organization.assistantName().length() > 0) {
QVersitProperty property;
property.setName(QLatin1String("X-ASSISTANT"));
- setEscapedValue(property,organization.assistantName());
+ property.setValue(organization.assistantName());
document.addProperty(property);
}
if (organization.role().length() > 0) {
QVersitProperty property;
property.setName(QLatin1String("ROLE"));
- setEscapedValue(property,organization.role());
+ property.setValue(organization.role());
document.addProperty(property);
}
}
+bool QVersitContactExporterPrivate::encodeRingtone(QVersitProperty &property, const QContactDetail &detail)
+{
+ QContactRingtone ringtone = static_cast<QContactRingtone>(detail);
+ Q_ASSERT(property.name() == QLatin1String("SOUND"));
+ return encodeContentFromFile(ringtone.audioRingtoneUrl().toLocalFile(), property);
+}
+
/*!
- * Encode avatar content into the Versit Document
+ * Encode thumbnail content into the Versit Document
+ */
+bool QVersitContactExporterPrivate::encodeThumbnail(
+ QVersitProperty& property,
+ const QContactDetail& detail)
+{
+ QContactThumbnail contactThumbnail = static_cast<QContactThumbnail>(detail);
+ property.setName(QLatin1String("PHOTO"));
+ QImage image = contactThumbnail.thumbnail();
+ if (image.isNull())
+ return false;
+ QByteArray imageData;
+ QBuffer buffer(&imageData);
+ buffer.open(QIODevice::WriteOnly);
+ // Always store a pixmap as a PNG.
+ if (!image.save(&buffer, "PNG")) {
+ return false;
+ }
+ property.setValue(imageData);
+ property.insertParameter(QLatin1String("TYPE"), QLatin1String("PNG"));
+ return true;
+}
+
+/*!
+ * Encode avatar URIs into the Versit Document
*/
bool QVersitContactExporterPrivate::encodeAvatar(
QVersitProperty& property,
const QContactDetail& detail)
{
+ property.setName(QLatin1String("PHOTO"));
QContactAvatar contactAvatar = static_cast<QContactAvatar>(detail);
- bool encoded = false;
- QString propertyName;
- if (contactAvatar.subType() == QContactAvatar::SubTypeImage) {
- propertyName = QLatin1String("PHOTO");
- } else if (contactAvatar.subType() == QContactAvatar::SubTypeAudioRingtone) {
- propertyName = QLatin1String("SOUND");
+ 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());
+ return true;
} else {
- // NOP
+ return encodeContentFromFile(contactAvatar.imageUrl().toString(), property);
}
- if (propertyName.length() > 0) {
- encoded = encodeContentFromFile(contactAvatar.avatar(), property);
- if (!encoded)
- encoded = encodeContentFromPixmap(contactAvatar.pixmap(), property);
- if (encoded)
- property.setName(propertyName);
- }
- return encoded;
}
/*!
@@ -436,7 +495,7 @@
QContactDetail& detail)
{
QContactGender gender = static_cast<QContactGender>(detail);
- setEscapedValue(property,gender.gender());
+ property.setValue(gender.gender());
}
/*!
@@ -448,27 +507,55 @@
{
QContactNickname nicknameDetail = static_cast<QContactNickname>(detail);
QVersitProperty property;
- property.setName(QLatin1String("X-NICKNAME"));
bool found = false;
- foreach (QVersitProperty currentProperty, document.properties()) {
+ // XXX TODO: ensure it works for both X-NICKNAME and NICKNAME
+ foreach (const QVersitProperty& currentProperty, document.properties()) {
if (currentProperty.name() == QLatin1String("X-NICKNAME")) {
property = currentProperty;
found = true;
break;
}
}
- QString value(property.value());
- if (found)
- value += QLatin1Char(',');
- QString nickname = escape(nicknameDetail.nickname());
- value.append(nickname);
+ QStringList value(property.variantValue().toStringList());
+ if (!found)
+ property.setName(QLatin1String("X-NICKNAME"));
+ value.append(nicknameDetail.nickname());
property.setValue(value);
+ property.setValueType(QVersitProperty::ListType);
// Replace the current property
document.removeProperties(QLatin1String("X-NICKNAME"));
document.addProperty(property);
}
/*!
+ * Encodes a contact tag into the Versit Document
+ */
+void QVersitContactExporterPrivate::encodeTag(
+ QVersitDocument& document,
+ const QContactDetail& detail)
+{
+ QContactTag tagDetail = static_cast<QContactTag>(detail);
+ QVersitProperty property;
+ bool found = false;
+ foreach (const QVersitProperty& currentProperty, document.properties()) {
+ if (currentProperty.name() == QLatin1String("CATEGORIES")) {
+ property = currentProperty;
+ found = true;
+ break;
+ }
+ }
+ QStringList value(property.variantValue().toStringList());
+ if (!found)
+ property.setName(QLatin1String("CATEGORIES"));
+ value.append(tagDetail.tag());
+ property.setValue(value);
+ property.setValueType(QVersitProperty::ListType);
+ // Replace the current property
+ document.removeProperties(QLatin1String("CATEGORIES"));
+ document.addProperty(property);
+}
+
+/*!
* Encode anniversary information into Versit Document
*/
void QVersitContactExporterPrivate::encodeAnniversary(
@@ -500,7 +587,7 @@
if (subTypes.contains(QContactOnlineAccount::SubTypeImpp))
name = QLatin1String("X-IMPP");
property.setName(name);
- setEscapedValue(property,onlineAccount.accountUri());
+ property.setValue(onlineAccount.accountUri());
}
return encoded;
}
@@ -517,15 +604,15 @@
if (family.spouse().size()) {
QVersitProperty property;
property.setName(QLatin1String("X-SPOUSE"));
- setEscapedValue(property,family.spouse());
+ property.setValue(family.spouse());
document.addProperty(property);
}
if (family.children().size()) {
QVersitProperty property;
property.setName(QLatin1String("X-CHILDREN"));
- QString children = family.children().join(QLatin1String(","));
- setEscapedValue(property,children);
+ property.setValue(family.children());
+ property.setValueType(QVersitProperty::ListType);
document.addProperty(property);
}
return false;
@@ -544,7 +631,7 @@
QContactDisplayLabel displayLabel = static_cast<QContactDisplayLabel>(detail);
if (displayLabel.label().size()) {
encoded = true;
- setEscapedValue(property,displayLabel.label());
+ property.setValue(displayLabel.label());
} else {
QContactDetail contactDetail;
for (int i = 0; i < contact.details().count(); i++) {
@@ -563,7 +650,7 @@
name.firstName().length() ||
name.lastName().length()) {
encoded = true;
- property.setValue(escape(value));
+ property.setValue(value);
}
}
return encoded;
@@ -635,49 +722,3 @@
property.setValue(value);
return encodeContent;
}
-
-/*!
- * Encode embedded content from the given \a pixmap into \a property.
- */
-bool QVersitContactExporterPrivate::encodeContentFromPixmap(const QPixmap& pixmap,
- QVersitProperty& property)
-{
- if (pixmap.isNull())
- return false;
- QByteArray imageData;
- QBuffer buffer(&imageData);
- buffer.open(QIODevice::WriteOnly);
- // Always store a pixmap as a PNG.
- if (!pixmap.save(&buffer, "PNG")) {
- return false;
- }
- property.setValue(imageData);
- property.insertParameter(QLatin1String("TYPE"), QLatin1String("PNG"));
- return true;
-}
-
-/*!
- * Escapes \a value if necessary and sets it to \a property
- */
-void QVersitContactExporterPrivate::setEscapedValue(
- QVersitProperty& property,
- const QString& value)
-{
- QString escapedValue(escape(value));
- property.setValue(escapedValue);
-}
-
-/*!
- * Escapes \a value if necessary.
- * For vCard there is no concept of escaping the property values.
- * Starting from 3.0 the property values having certain special
- * characters should be escaped.
- */
-QString QVersitContactExporterPrivate::escape(const QString& value)
-{
- QString escaped(value);
- if (mVersitType != QVersitDocument::VCard21Type) {
- VersitUtils::backSlashEscape(escaped);
- }
- return escaped;
-}