qtmobility/src/versit/qversitcontactimporter_p.cpp
changeset 4 90517678cc4f
parent 1 2b40d63a9c3d
child 8 71781823f776
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
    43 #include "qversitcontactimporter_p.h"
    43 #include "qversitcontactimporter_p.h"
    44 #include "qversitdocument.h"
    44 #include "qversitdocument.h"
    45 #include "qversitproperty.h"
    45 #include "qversitproperty.h"
    46 #include "qmobilityglobal.h"
    46 #include "qmobilityglobal.h"
    47 
    47 
       
    48 #include <qcontactmanagerengine.h>
    48 #include <qcontact.h>
    49 #include <qcontact.h>
    49 #include <qcontactdetail.h>
    50 #include <qcontactdetail.h>
    50 #include <qcontactname.h>
    51 #include <qcontactname.h>
    51 #include <qcontactphonenumber.h>
    52 #include <qcontactphonenumber.h>
    52 #include <qcontactaddress.h>
    53 #include <qcontactaddress.h>
    63 #include <qcontactgeolocation.h>
    64 #include <qcontactgeolocation.h>
    64 #include <qcontactnote.h>
    65 #include <qcontactnote.h>
    65 #include <qcontactonlineaccount.h>
    66 #include <qcontactonlineaccount.h>
    66 #include <qcontactfamily.h>
    67 #include <qcontactfamily.h>
    67 #include <qcontactdisplaylabel.h>
    68 #include <qcontactdisplaylabel.h>
       
    69 #include <qcontactthumbnail.h>
       
    70 #include <qcontactringtone.h>
    68 
    71 
    69 #include <QHash>
    72 #include <QHash>
    70 #include <QFile>
    73 #include <QFile>
    71 
    74 
    72 QTM_USE_NAMESPACE
    75 QTM_USE_NAMESPACE
   120 }
   123 }
   121 
   124 
   122 /*!
   125 /*!
   123  * Generates a QContact from \a versitDocument.
   126  * Generates a QContact from \a versitDocument.
   124  */
   127  */
   125 QContact QVersitContactImporterPrivate::importContact(
   128 bool QVersitContactImporterPrivate::importContact(
   126      const QVersitDocument& document, int contactIndex)
   129         const QVersitDocument& document, int contactIndex, QContact* contact,
   127 {
   130         QVersitContactImporter::Error* error)
   128     QContact contact;
   131 {
       
   132     if (document.type() != QVersitDocument::VCard21Type
       
   133         && document.type() != QVersitDocument::VCard30Type) {
       
   134         *error = QVersitContactImporter::InvalidDocumentError;
       
   135         return false;
       
   136     }
   129     const QList<QVersitProperty> properties = document.properties();
   137     const QList<QVersitProperty> properties = document.properties();
       
   138     if (properties.size() == 0) {
       
   139         *error = QVersitContactImporter::EmptyDocumentError;
       
   140         return false;
       
   141     }
       
   142 
   130     // First, do the properties with PREF set so they appear first in the contact details
   143     // First, do the properties with PREF set so they appear first in the contact details
   131     foreach (const QVersitProperty& property, properties) {
   144     foreach (const QVersitProperty& property, properties) {
   132         if (property.parameters().contains(QLatin1String("TYPE"), QLatin1String("PREF")))
   145         if (property.parameters().contains(QLatin1String("TYPE"), QLatin1String("PREF")))
   133             importProperty(document, property, contactIndex, &contact);
   146             importProperty(document, property, contactIndex, contact);
   134     }
   147     }
   135     // ... then, do the rest of the properties.
   148     // ... then, do the rest of the properties.
   136     foreach (const QVersitProperty& property, properties) {
   149     foreach (const QVersitProperty& property, properties) {
   137         if (!property.parameters().contains(QLatin1String("TYPE"), QLatin1String("PREF")))
   150         if (!property.parameters().contains(QLatin1String("TYPE"), QLatin1String("PREF")))
   138             importProperty(document, property, contactIndex, &contact);
   151             importProperty(document, property, contactIndex, contact);
   139     }
   152     }
   140 
   153 
   141     contact.setType(QContactType::TypeContact);
   154     contact->setType(QContactType::TypeContact);
   142     return contact;
   155     QContactManagerEngine::setContactDisplayLabel(contact, QVersitContactImporterPrivate::synthesizedDisplayLabel(*contact));
       
   156     return true;
   143 }
   157 }
   144 
   158 
   145 void QVersitContactImporterPrivate::importProperty(
   159 void QVersitContactImporterPrivate::importProperty(
   146         const QVersitDocument& document, const QVersitProperty& property, int contactIndex,
   160         const QVersitDocument& document, const QVersitProperty& property, int contactIndex,
   147         QContact* contact) const
   161         QContact* contact) const
   164         success = createGeoLocation(property, contact);
   178         success = createGeoLocation(property, contact);
   165     } else if (detailDefinitionName == QContactOrganization::DefinitionName) {
   179     } else if (detailDefinitionName == QContactOrganization::DefinitionName) {
   166         success = createOrganization(property, contact);
   180         success = createOrganization(property, contact);
   167     } else if (detailDefinitionName == QContactNickname::DefinitionName) {
   181     } else if (detailDefinitionName == QContactNickname::DefinitionName) {
   168         success = createNicknames(property, contact);
   182         success = createNicknames(property, contact);
   169     } else if (detailDefinitionName == QContactAvatar::DefinitionName) {
   183     } else if (detailDefinitionName == QContactRingtone::DefinitionName) {
   170         success = createAvatar(property,detailDefinition.second, contact);
   184         success = createRingtone(property, contact);
       
   185     } else if (detailDefinitionName == QContactThumbnail::DefinitionName) {
       
   186         success = createThumbnail(property, contact);
   171     } else if (detailDefinitionName == QContactTimestamp::DefinitionName) {
   187     } else if (detailDefinitionName == QContactTimestamp::DefinitionName) {
   172         success = createTimeStamp(property, contact);
   188         success = createTimeStamp(property, contact);
   173     } else if (detailDefinitionName == QContactPhoneNumber::DefinitionName) {
   189     } else if (detailDefinitionName == QContactPhoneNumber::DefinitionName) {
   174         success = createPhone(property, contact);
   190         success = createPhone(property, contact);
   175     } else if (detailDefinitionName == QContactAnniversary::DefinitionName) {
   191     } else if (detailDefinitionName == QContactAnniversary::DefinitionName) {
   176         success = createAnniversary(property, contact);
   192         success = createAnniversary(property, contact);
   177     } else if (detailDefinitionName == QContactFamily::DefinitionName) {
   193     } else if (detailDefinitionName == QContactFamily::DefinitionName) {
   178         success = createFamily(property, contact);
   194         success = createFamily(property, contact);
   179     } else if (detailDefinitionName == QContactOnlineAccount::DefinitionName) {
   195     } else if (detailDefinitionName == QContactOnlineAccount::DefinitionName) {
   180         success = createOnlineAccount(property, contact);
   196         success = createOnlineAccount(property, contact);
       
   197     } else if (detailDefinitionName == QContactTag::DefinitionName) {
       
   198         success = createTags(property, contact);
   181     } else if (detailDefinitionName == QContactDisplayLabel::DefinitionName) {
   199     } else if (detailDefinitionName == QContactDisplayLabel::DefinitionName) {
   182         // This actually sets the QContactName's customLabel field (not QContactDisplayLabel)
   200         // This actually sets the QContactName's customLabel field (not QContactDisplayLabel)
   183         success = createLabel(property, contact);
   201         success = createCustomLabel(property, contact);
   184     } else {
   202     } else {
   185         // Look up mDetailMappings for a simple mapping from property to detail.
   203         // Look up mDetailMappings for a simple mapping from property to detail.
   186         success = createNameValueDetail(property, contact);
   204         success = createNameValueDetail(property, contact);
   187     }
   205     }
   188 
   206 
   197 {
   215 {
   198     QContactName name;
   216     QContactName name;
   199     QContactDetail detail = contact->detail(QContactName::DefinitionName);
   217     QContactDetail detail = contact->detail(QContactName::DefinitionName);
   200     if (!detail.isEmpty()) {
   218     if (!detail.isEmpty()) {
   201         // If multiple name properties exist,
   219         // If multiple name properties exist,
   202         // discard all except the first occurence
   220         // discard all except the first occurrence
   203         if (!detail.value(QContactName::FieldFirstName).isEmpty())
   221         if (!detail.value(QContactName::FieldFirstName).isEmpty())
   204             return false;
   222             return false;
   205         else
   223         else
   206             name = QContactName(static_cast<QContactName>(detail));
   224             name = QContactName(static_cast<QContactName>(detail));
   207     }
   225     }
   208 
   226 
   209     QStringList values = property.value().split(QLatin1Char(';'));
   227     QVariant variant = property.variantValue();
       
   228     if (property.valueType() != QVersitProperty::CompoundType
       
   229             || variant.type() != QVariant::StringList)
       
   230         return false;
       
   231     QStringList values = variant.toStringList();
   210     name.setLastName(takeFirst(values));
   232     name.setLastName(takeFirst(values));
   211     name.setFirstName(takeFirst(values));
   233     name.setFirstName(takeFirst(values));
   212     name.setMiddleName(takeFirst(values));
   234     name.setMiddleName(takeFirst(values));
   213     name.setPrefix(takeFirst(values));
   235     name.setPrefix(takeFirst(values));
   214     name.setSuffix(takeFirst(values));
   236     name.setSuffix(takeFirst(values));
   237 bool QVersitContactImporterPrivate::createAddress(
   259 bool QVersitContactImporterPrivate::createAddress(
   238     const QVersitProperty& property, QContact* contact) const
   260     const QVersitProperty& property, QContact* contact) const
   239 {
   261 {
   240     QContactAddress address;
   262     QContactAddress address;
   241 
   263 
   242     QStringList addressParts = property.value().split(QLatin1Char(';'));
   264     QVariant variant = property.variantValue();
       
   265     if (property.valueType() != QVersitProperty::CompoundType
       
   266             || variant.type() != QVariant::StringList)
       
   267         return false;
       
   268     QStringList addressParts = variant.toStringList();
   243     address.setPostOfficeBox(takeFirst(addressParts));
   269     address.setPostOfficeBox(takeFirst(addressParts));
   244     // There is no setter for the Extended Address in QContactAddress:
   270     // There is no setter for the Extended Address in QContactAddress:
   245     if (!addressParts.isEmpty())
   271     if (!addressParts.isEmpty())
   246         addressParts.removeFirst();
   272         addressParts.removeFirst();
   247     address.setStreet(takeFirst(addressParts));
   273     address.setStreet(takeFirst(addressParts));
   264     QContactOrganization organization;
   290     QContactOrganization organization;
   265     QPair<QString,QString> detailNameAndFieldName =
   291     QPair<QString,QString> detailNameAndFieldName =
   266         mDetailMappings.value(property.name());
   292         mDetailMappings.value(property.name());
   267     QString fieldName = detailNameAndFieldName.second;
   293     QString fieldName = detailNameAndFieldName.second;
   268     QList<QContactOrganization> organizations = contact->details<QContactOrganization>();
   294     QList<QContactOrganization> organizations = contact->details<QContactOrganization>();
   269     foreach(QContactOrganization current, organizations) {
   295     foreach(const QContactOrganization& current, organizations) {
   270         if (current.value(fieldName).length() == 0) {
   296         if (current.value(fieldName).length() == 0) {
   271             organization = current;
   297             organization = current;
   272             break;
   298             break;
   273         }
   299         }
   274     }
   300     }
   276         setOrganizationNames(organization, property);
   302         setOrganizationNames(organization, property);
   277     } else if (fieldName == QContactOrganization::FieldTitle) {
   303     } else if (fieldName == QContactOrganization::FieldTitle) {
   278         organization.setTitle(property.value());
   304         organization.setTitle(property.value());
   279     } else if (fieldName == QContactOrganization::FieldRole) {
   305     } else if (fieldName == QContactOrganization::FieldRole) {
   280         organization.setRole(property.value());
   306         organization.setRole(property.value());
   281     } else if (fieldName == QContactOrganization::FieldLogo) {
   307     } else if (fieldName == QContactOrganization::FieldLogoUrl) {
   282         setOrganizationLogo(organization, property);
   308         setOrganizationLogo(organization, property);
   283     } else if (fieldName == QContactOrganization::FieldAssistantName) {
   309     } else if (fieldName == QContactOrganization::FieldAssistantName) {
   284         organization.setAssistantName(property.value());
   310         organization.setAssistantName(property.value());
   285     } else {
   311     } else {
   286         return false;
   312         return false;
   294  * Set the organization name and department(s) from \a property.
   320  * Set the organization name and department(s) from \a property.
   295  */
   321  */
   296 void QVersitContactImporterPrivate::setOrganizationNames(
   322 void QVersitContactImporterPrivate::setOrganizationNames(
   297     QContactOrganization& organization, const QVersitProperty& property) const
   323     QContactOrganization& organization, const QVersitProperty& property) const
   298 {
   324 {
   299     QString value = property.value();
   325     QVariant variant = property.variantValue();
   300     int firstSemicolon = value.indexOf(QLatin1Char(';'));
   326     if (property.valueType() == QVersitProperty::CompoundType
   301     if (firstSemicolon >= 0) {
   327         && variant.type() == QVariant::StringList) {
   302         organization.setName(value.left(firstSemicolon));
   328         QStringList values = variant.toStringList();
   303         QString departmentsStr(value.mid(firstSemicolon+1));
   329         organization.setName(takeFirst(values));
   304         QStringList departments =
   330         organization.setDepartment(values);
   305             departmentsStr.split(QLatin1Char(';'), QString::SkipEmptyParts);
       
   306         organization.setDepartment(departments);
       
   307     } else {
       
   308         organization.setName(value);
       
   309     }
   331     }
   310 }
   332 }
   311 
   333 
   312 /*!
   334 /*!
   313  * Set the organization logo from \a property.
   335  * Set the organization logo from \a property.
   317 {
   339 {
   318     QString location;
   340     QString location;
   319     QByteArray data;
   341     QByteArray data;
   320     saveDataFromProperty(property, &location, &data);
   342     saveDataFromProperty(property, &location, &data);
   321     if (!location.isEmpty())
   343     if (!location.isEmpty())
   322         org.setLogo(location);
   344         org.setLogoUrl(QUrl(location));
   323 }
   345 }
   324 
   346 
   325 /*!
   347 /*!
   326  * Creates a QContactTimeStamp from \a property
   348  * Creates a QContactTimeStamp from \a property
   327  */
   349  */
   377  * Creates QContactNicknames from \a property and adds them to \a contact
   399  * Creates QContactNicknames from \a property and adds them to \a contact
   378  */
   400  */
   379 bool QVersitContactImporterPrivate::createNicknames(
   401 bool QVersitContactImporterPrivate::createNicknames(
   380     const QVersitProperty& property, QContact* contact) const
   402     const QVersitProperty& property, QContact* contact) const
   381 {
   403 {
   382     QStringList values = property.value().split(QLatin1Char(','), QString::SkipEmptyParts);
   404     QVariant variant = property.variantValue();
       
   405     if (property.valueType() != QVersitProperty::ListType
       
   406             || variant.type() != QVariant::StringList)
       
   407         return false;
       
   408     QStringList values = variant.toStringList();
   383     QStringList contexts = extractContexts(property);
   409     QStringList contexts = extractContexts(property);
   384     foreach(QString value, values) {
   410     foreach(const QString& value, values) {
   385         QContactNickname nickName;
   411         QContactNickname nickName;
   386         nickName.setNickname(value);
   412         nickName.setNickname(value);
   387         saveDetailWithContext(contact, &nickName, extractContexts(property));
   413         saveDetailWithContext(contact, &nickName, contexts);
       
   414     }
       
   415     return true;
       
   416 }
       
   417 
       
   418 /*!
       
   419  * Creates QContactTags from \a property and adds them to \a contact
       
   420  */
       
   421 bool QVersitContactImporterPrivate::createTags(
       
   422     const QVersitProperty& property, QContact* contact) const
       
   423 {
       
   424     QVariant variant = property.variantValue();
       
   425     if (property.valueType() != QVersitProperty::ListType
       
   426             || variant.type() != QVariant::StringList)
       
   427         return false;
       
   428     QStringList values = variant.toStringList();
       
   429     QStringList contexts = extractContexts(property);
       
   430     foreach(const QString& value, values) {
       
   431         QContactTag tag;
       
   432         tag.setTag(value);
       
   433         saveDetailWithContext(contact, &tag, contexts);
   388     }
   434     }
   389     return true;
   435     return true;
   390 }
   436 }
   391 
   437 
   392 /*!
   438 /*!
   414 
   460 
   415     saveDetailWithContext(contact, &onlineAccount, extractContexts(property));
   461     saveDetailWithContext(contact, &onlineAccount, extractContexts(property));
   416     return true;
   462     return true;
   417 }
   463 }
   418 
   464 
   419 /*!
   465 bool QVersitContactImporterPrivate::createRingtone(const QVersitProperty &property,
   420  * Creates a QContactAvatar from \a property
   466                                                    QContact *contact) const
   421  */
       
   422 bool QVersitContactImporterPrivate::createAvatar(
       
   423     const QVersitProperty& property, const QString& subType, QContact* contact) const
       
   424 {
   467 {
   425     QString location;
   468     QString location;
   426     QByteArray data;
   469     QByteArray data;
   427     if (!(saveDataFromProperty(property, &location, &data)))
   470     if (saveDataFromProperty(property, &location, &data) && !location.isEmpty()) {
   428         return false;
   471         QContactRingtone ringtone;
   429 
   472         ringtone.setAudioRingtoneUrl(location);
   430     QContactAvatar avatar;
   473         saveDetailWithContext(contact, &ringtone, extractContexts(property));
   431     if (!location.isEmpty())
   474         return true;
   432         avatar.setAvatar(location);
   475     }
   433     // Creating a pixmap in a non-GUI thread crashes on S60.
   476     return false;
   434     // XXX reenable this when the QtContacts stores QImages.
   477 }
   435 //    if (subType == QContactAvatar::SubTypeImage && !data.isEmpty()) {
   478 
   436 //        QPixmap pixmap;
   479 /*!
   437 //        if (pixmap.loadFromData(data))
   480  * Creates a QContactAvatar from \a property
   438 //            avatar.setPixmap(pixmap);
   481  */
   439 //    }
   482 bool QVersitContactImporterPrivate::createThumbnail(
   440     avatar.setSubType(subType);
   483     const QVersitProperty& property, QContact* contact) const
   441 
   484 {
   442     saveDetailWithContext(contact, &avatar, extractContexts(property));
   485     QString location;
   443     return true;
   486     QByteArray data;
       
   487     bool success = false;
       
   488 
       
   489     if (saveDataFromProperty(property, &location, &data) && !location.isEmpty()) {
       
   490         QContactAvatar avatar;
       
   491         avatar.setImageUrl(location);
       
   492         saveDetailWithContext(contact, &avatar, extractContexts(property));
       
   493         success = true;
       
   494     }
       
   495     if (!data.isEmpty()) {
       
   496         QImage image;
       
   497         if (image.loadFromData(data)) {
       
   498             QContactThumbnail thumbnail = contact->detail<QContactThumbnail>();
       
   499             // In the case of multiple thumbnails, pick the smallest one.
       
   500             if (thumbnail.isEmpty() || image.byteCount() < thumbnail.thumbnail().byteCount()) {
       
   501                 thumbnail.setThumbnail(image);
       
   502             }
       
   503             saveDetailWithContext(contact, &thumbnail, extractContexts(property));
       
   504             success = true;
       
   505         }
       
   506     }
       
   507 
       
   508     return success;
   444 }
   509 }
   445 
   510 
   446 /*!
   511 /*!
   447  * Creates a QContactGeoLocation from \a property
   512  * Creates a QContactGeoLocation from \a property
   448  */
   513  */
   449 bool QVersitContactImporterPrivate::createGeoLocation(
   514 bool QVersitContactImporterPrivate::createGeoLocation(
   450     const QVersitProperty& property, QContact* contact) const
   515     const QVersitProperty& property, QContact* contact) const
   451 {
   516 {
   452     QContactGeoLocation geo;
   517     QContactGeoLocation geo;
   453     QStringList values = property.value().split(QLatin1Char(','));
   518     QVariant variant = property.variantValue();
       
   519     if (property.valueType() != QVersitProperty::CompoundType
       
   520             || variant.type() != QVariant::StringList)
       
   521         return false;
       
   522     QStringList values = variant.toStringList();
   454     geo.setLongitude(takeFirst(values).toDouble());
   523     geo.setLongitude(takeFirst(values).toDouble());
   455     geo.setLatitude(takeFirst(values).toDouble());
   524     geo.setLatitude(takeFirst(values).toDouble());
   456 
   525 
   457     saveDetailWithContext(contact, &geo, extractContexts(property));
   526     saveDetailWithContext(contact, &geo, extractContexts(property));
   458     return true;
   527     return true;
   467     QString val = property.value();
   536     QString val = property.value();
   468     QContactFamily family = contact->detail<QContactFamily>();
   537     QContactFamily family = contact->detail<QContactFamily>();
   469     if (property.name() == QLatin1String("X-SPOUSE")) {
   538     if (property.name() == QLatin1String("X-SPOUSE")) {
   470         family.setSpouse(val);
   539         family.setSpouse(val);
   471     } else if (property.name() == QLatin1String("X-CHILDREN")) {
   540     } else if (property.name() == QLatin1String("X-CHILDREN")) {
   472         family.setChildren(val.split(QLatin1String(",")));
   541         QVariant variant = property.variantValue();
       
   542         if (property.valueType() != QVersitProperty::ListType
       
   543                 || variant.type() != QVariant::StringList)
       
   544             return false;
       
   545         QStringList values = variant.toStringList();
       
   546         family.setChildren(values);
   473     }
   547     }
   474 
   548 
   475     saveDetailWithContext(contact, &family, extractContexts(property));
   549     saveDetailWithContext(contact, &family, extractContexts(property));
   476     return true;
   550     return true;
   477 }
   551 }
   495 }
   569 }
   496 
   570 
   497 /*!
   571 /*!
   498  * Creates a simple name-value contact detail.
   572  * Creates a simple name-value contact detail.
   499  */
   573  */
   500 bool QVersitContactImporterPrivate::createLabel(
   574 bool QVersitContactImporterPrivate::createCustomLabel(
   501     const QVersitProperty& property, QContact* contact) const
   575     const QVersitProperty& property, QContact* contact) const
   502 {
   576 {
   503     QContactName name;
   577     QContactName name;
   504     QContactName existingName = contact->detail<QContactName>();
   578     QContactName existingName = contact->detail<QContactName>();
   505     if (!existingName.isEmpty()) {
   579     if (!existingName.isEmpty()) {
   519     const QVersitProperty& property) const
   593     const QVersitProperty& property) const
   520 {
   594 {
   521     QStringList types =
   595     QStringList types =
   522         property.parameters().values(QLatin1String("TYPE"));
   596         property.parameters().values(QLatin1String("TYPE"));
   523     QStringList contexts;
   597     QStringList contexts;
   524     foreach (QString type, types) {
   598     foreach (const QString& type, types) {
   525         QString value = mContextMappings.value(type);
   599         QString value = mContextMappings.value(type);
   526         if (value.length() > 0)
   600         if (value.length() > 0)
   527             contexts.append(value);
   601             contexts.append(value);
   528     }
   602     }
   529     return contexts;
   603     return contexts;
   536     const QVersitProperty& property) const
   610     const QVersitProperty& property) const
   537 {
   611 {
   538     QStringList types =
   612     QStringList types =
   539         property.parameters().values(QLatin1String("TYPE"));
   613         property.parameters().values(QLatin1String("TYPE"));
   540     QStringList subTypes;
   614     QStringList subTypes;
   541     foreach (QString type, types) {
   615     foreach (const QString& type, types) {
   542         QString subType = mSubTypeMappings.value(type);
   616         QString subType = mSubTypeMappings.value(type);
   543         if (subType.length() > 0)
   617         if (subType.length() > 0)
   544             subTypes += subType;
   618             subTypes += subType;
   545     }
   619     }
   546     return subTypes;
   620     return subTypes;
   618 {
   692 {
   619     if (!contexts.isEmpty())
   693     if (!contexts.isEmpty())
   620         detail->setContexts(contexts);
   694         detail->setContexts(contexts);
   621     contact->saveDetail(detail);
   695     contact->saveDetail(detail);
   622 }
   696 }
       
   697 
       
   698 /*! Synthesize the display label from the name of the contact, or, failing that, the nickname of
       
   699 the contact, or failing that, the organisation of the contact.
       
   700 Returns the synthesized display label.
       
   701  */
       
   702 QString QVersitContactImporterPrivate::synthesizedDisplayLabel(const QContact& contact)
       
   703 {
       
   704     /* XXX This is copied and modified from QContactManagerEngine.  This should be made a public
       
   705        static function in QCME and called here */
       
   706     QList<QContactName> allNames = contact.details<QContactName>();
       
   707 
       
   708     const QLatin1String space(" ");
       
   709 
       
   710     // synthesize the display label from the name.
       
   711     foreach (const QContactName& name, allNames) {
       
   712         if (!name.customLabel().isEmpty()) {
       
   713             // default behaviour is to allow the user to define a custom display label.
       
   714             return name.customLabel();
       
   715         }
       
   716 
       
   717         QString result;
       
   718         if (!name.value(QContactName::FieldPrefix).trimmed().isEmpty()) {
       
   719            result += name.value(QContactName::FieldPrefix);
       
   720         }
       
   721         if (!name.value(QContactName::FieldFirstName).trimmed().isEmpty()) {
       
   722             if (!result.isEmpty())
       
   723                 result += space;
       
   724             result += name.value(QContactName::FieldFirstName);
       
   725         }
       
   726         if (!name.value(QContactName::FieldMiddleName).trimmed().isEmpty()) {
       
   727             if (!result.isEmpty())
       
   728                 result += space;
       
   729             result += name.value(QContactName::FieldMiddleName);
       
   730         }
       
   731         if (!name.value(QContactName::FieldLastName).trimmed().isEmpty()) {
       
   732             if (!result.isEmpty())
       
   733                 result += space;
       
   734             result += name.value(QContactName::FieldLastName);
       
   735         }
       
   736         if (!name.value(QContactName::FieldSuffix).trimmed().isEmpty()) {
       
   737             if (!result.isEmpty())
       
   738                 result += space;
       
   739             result += name.value(QContactName::FieldSuffix);
       
   740         }
       
   741         if (!result.isEmpty())
       
   742             return result;
       
   743     }
       
   744 
       
   745     QList<QContactNickname> allNicknames = contact.details<QContactNickname>();
       
   746     foreach (const QContactNickname& nickname, allNicknames) {
       
   747         if (!nickname.nickname().isEmpty())
       
   748             return nickname.nickname();
       
   749     }
       
   750 
       
   751     /* Well, we had no non empty names. if we have orgs, fall back to those */
       
   752     QList<QContactOrganization> allOrgs = contact.details<QContactOrganization>();
       
   753     foreach (const QContactOrganization& org, allOrgs) {
       
   754         if (!org.name().isEmpty())
       
   755             return org.name();
       
   756     }
       
   757 
       
   758     return QString();
       
   759 }