140 return false; |
140 return false; |
141 } |
141 } |
142 |
142 |
143 // 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 |
144 foreach (const QVersitProperty& property, properties) { |
144 foreach (const QVersitProperty& property, properties) { |
145 if (property.parameters().contains(QLatin1String("TYPE"), QLatin1String("PREF"))) |
145 QStringList typeParameters = property.parameters().values(QLatin1String("TYPE")); |
|
146 if (typeParameters.contains(QLatin1String("PREF"), Qt::CaseInsensitive)) |
146 importProperty(document, property, contactIndex, contact); |
147 importProperty(document, property, contactIndex, contact); |
147 } |
148 } |
148 // ... then, do the rest of the properties. |
149 // ... then, do the rest of the properties. |
149 foreach (const QVersitProperty& property, properties) { |
150 foreach (const QVersitProperty& property, properties) { |
150 if (!property.parameters().contains(QLatin1String("TYPE"), QLatin1String("PREF"))) |
151 QStringList typeParameters = property.parameters().values(QLatin1String("TYPE")); |
|
152 if (!typeParameters.contains(QLatin1String("PREF"), Qt::CaseInsensitive)) |
151 importProperty(document, property, contactIndex, contact); |
153 importProperty(document, property, contactIndex, contact); |
152 } |
154 } |
153 |
155 |
154 contact->setType(QContactType::TypeContact); |
156 contact->setType(QContactType::TypeContact); |
155 QContactManagerEngine::setContactDisplayLabel(contact, QVersitContactImporterPrivate::synthesizedDisplayLabel(*contact)); |
157 QContactManagerEngine::setContactDisplayLabel(contact, QVersitContactImporterPrivate::synthesizedDisplayLabel(*contact)); |
195 } else if (detailDefinitionName == QContactOnlineAccount::DefinitionName) { |
197 } else if (detailDefinitionName == QContactOnlineAccount::DefinitionName) { |
196 success = createOnlineAccount(property, contact); |
198 success = createOnlineAccount(property, contact); |
197 } else if (detailDefinitionName == QContactTag::DefinitionName) { |
199 } else if (detailDefinitionName == QContactTag::DefinitionName) { |
198 success = createTags(property, contact); |
200 success = createTags(property, contact); |
199 } else if (detailDefinitionName == QContactDisplayLabel::DefinitionName) { |
201 } else if (detailDefinitionName == QContactDisplayLabel::DefinitionName) { |
200 // This actually sets the QContactName's customLabel field (not QContactDisplayLabel) |
|
201 success = createCustomLabel(property, contact); |
202 success = createCustomLabel(property, contact); |
202 } else { |
203 } else { |
203 // Look up mDetailMappings for a simple mapping from property to detail. |
204 // Look up mDetailMappings for a simple mapping from property to detail. |
204 success = createNameValueDetail(property, contact); |
205 success = createNameValueDetail(property, contact); |
205 } |
206 } |
227 QVariant variant = property.variantValue(); |
228 QVariant variant = property.variantValue(); |
228 if (property.valueType() != QVersitProperty::CompoundType |
229 if (property.valueType() != QVersitProperty::CompoundType |
229 || variant.type() != QVariant::StringList) |
230 || variant.type() != QVariant::StringList) |
230 return false; |
231 return false; |
231 QStringList values = variant.toStringList(); |
232 QStringList values = variant.toStringList(); |
232 name.setLastName(takeFirst(values)); |
233 QString value(takeFirst(values)); |
233 name.setFirstName(takeFirst(values)); |
234 if (!value.isEmpty()) |
234 name.setMiddleName(takeFirst(values)); |
235 name.setLastName(value); |
235 name.setPrefix(takeFirst(values)); |
236 value = takeFirst(values); |
236 name.setSuffix(takeFirst(values)); |
237 if (!value.isEmpty()) |
|
238 name.setFirstName(value); |
|
239 value = takeFirst(values); |
|
240 if (!value.isEmpty()) |
|
241 name.setMiddleName(value); |
|
242 value = takeFirst(values); |
|
243 if (!value.isEmpty()) |
|
244 name.setPrefix(value); |
|
245 value = takeFirst(values); |
|
246 if (!value.isEmpty()) |
|
247 name.setSuffix(value); |
237 |
248 |
238 saveDetailWithContext(contact, &name, extractContexts(property)); |
249 saveDetailWithContext(contact, &name, extractContexts(property)); |
239 return true; |
250 return true; |
240 } |
251 } |
241 |
252 |
244 */ |
255 */ |
245 bool QVersitContactImporterPrivate::createPhone( |
256 bool QVersitContactImporterPrivate::createPhone( |
246 const QVersitProperty& property, QContact* contact) const |
257 const QVersitProperty& property, QContact* contact) const |
247 { |
258 { |
248 QContactPhoneNumber phone; |
259 QContactPhoneNumber phone; |
|
260 QString value(property.value()); |
|
261 if (value.isEmpty()) |
|
262 return false; |
249 phone.setNumber(property.value()); |
263 phone.setNumber(property.value()); |
250 phone.setSubTypes(extractSubTypes(property)); |
264 QStringList subTypes(extractSubTypes(property)); |
251 if (property.name() == QLatin1String("X-ASSISTANT-TEL")) |
265 if (property.name() == QLatin1String("X-ASSISTANT-TEL")) |
252 phone.setSubTypes(QContactPhoneNumber::SubTypeAssistant); |
266 subTypes << QContactPhoneNumber::SubTypeAssistant; |
|
267 if (!subTypes.isEmpty()) |
|
268 phone.setSubTypes(subTypes); |
253 |
269 |
254 saveDetailWithContext(contact, &phone, extractContexts(property)); |
270 saveDetailWithContext(contact, &phone, extractContexts(property)); |
255 return true; |
271 return true; |
256 } |
272 } |
257 |
273 |
266 QVariant variant = property.variantValue(); |
282 QVariant variant = property.variantValue(); |
267 if (property.valueType() != QVersitProperty::CompoundType |
283 if (property.valueType() != QVersitProperty::CompoundType |
268 || variant.type() != QVariant::StringList) |
284 || variant.type() != QVariant::StringList) |
269 return false; |
285 return false; |
270 QStringList addressParts = variant.toStringList(); |
286 QStringList addressParts = variant.toStringList(); |
271 address.setPostOfficeBox(takeFirst(addressParts)); |
287 QString value(takeFirst(addressParts)); |
|
288 if (!value.isEmpty()) |
|
289 address.setPostOfficeBox(value); |
272 // There is no setter for the Extended Address in QContactAddress: |
290 // There is no setter for the Extended Address in QContactAddress: |
273 if (!addressParts.isEmpty()) |
291 if (!addressParts.isEmpty()) |
274 addressParts.removeFirst(); |
292 addressParts.removeFirst(); |
275 address.setStreet(takeFirst(addressParts)); |
293 value = takeFirst(addressParts); |
276 address.setLocality(takeFirst(addressParts)); |
294 if (!value.isEmpty()) |
277 address.setRegion(takeFirst(addressParts)); |
295 address.setStreet(value); |
278 address.setPostcode(takeFirst(addressParts)); |
296 value = takeFirst(addressParts); |
279 address.setCountry(takeFirst(addressParts)); |
297 if (!value.isEmpty()) |
280 address.setSubTypes(extractSubTypes(property)); |
298 address.setLocality(value); |
|
299 value = takeFirst(addressParts); |
|
300 if (!value.isEmpty()) |
|
301 address.setRegion(value); |
|
302 value = takeFirst(addressParts); |
|
303 if (!value.isEmpty()) |
|
304 address.setPostcode(value); |
|
305 value = takeFirst(addressParts); |
|
306 if (!value.isEmpty()) |
|
307 address.setCountry(value); |
|
308 QStringList subTypes(extractSubTypes(property)); |
|
309 if (!subTypes.isEmpty()) |
|
310 address.setSubTypes(subTypes); |
281 |
311 |
282 saveDetailWithContext(contact, &address, extractContexts(property)); |
312 saveDetailWithContext(contact, &address, extractContexts(property)); |
283 return true; |
313 return true; |
284 } |
314 } |
285 |
315 |
326 { |
356 { |
327 QVariant variant = property.variantValue(); |
357 QVariant variant = property.variantValue(); |
328 if (property.valueType() == QVersitProperty::CompoundType |
358 if (property.valueType() == QVersitProperty::CompoundType |
329 && variant.type() == QVariant::StringList) { |
359 && variant.type() == QVariant::StringList) { |
330 QStringList values = variant.toStringList(); |
360 QStringList values = variant.toStringList(); |
331 organization.setName(takeFirst(values)); |
361 QString name(takeFirst(values)); |
332 organization.setDepartment(values); |
362 if (!name.isEmpty()) |
|
363 organization.setName(name); |
|
364 if (!values.isEmpty()) |
|
365 organization.setDepartment(values); |
333 } |
366 } |
334 } |
367 } |
335 |
368 |
336 /*! |
369 /*! |
337 * Set the organization logo from \a property. |
370 * Set the organization logo from \a property. |
357 bool utc = value.endsWith(QLatin1Char('Z'), Qt::CaseInsensitive); |
390 bool utc = value.endsWith(QLatin1Char('Z'), Qt::CaseInsensitive); |
358 if (utc) |
391 if (utc) |
359 value.chop(1); // take away z from end; |
392 value.chop(1); // take away z from end; |
360 |
393 |
361 QDateTime dateTime = parseDateTime(value,QLatin1String("yyyyMMddThhmmss")); |
394 QDateTime dateTime = parseDateTime(value,QLatin1String("yyyyMMddThhmmss")); |
|
395 if (!dateTime.isValid()) |
|
396 return false; |
362 if (utc) |
397 if (utc) |
363 dateTime.setTimeSpec(Qt::UTC); |
398 dateTime.setTimeSpec(Qt::UTC); |
364 timeStamp.setLastModified(dateTime); |
399 timeStamp.setLastModified(dateTime); |
365 |
|
366 saveDetailWithContext(contact, &timeStamp, extractContexts(property)); |
400 saveDetailWithContext(contact, &timeStamp, extractContexts(property)); |
367 return true; |
401 return true; |
368 } |
402 } |
369 |
403 |
370 /*! |
404 /*! |
372 */ |
406 */ |
373 bool QVersitContactImporterPrivate::createAnniversary( |
407 bool QVersitContactImporterPrivate::createAnniversary( |
374 const QVersitProperty& property, QContact* contact) const |
408 const QVersitProperty& property, QContact* contact) const |
375 { |
409 { |
376 QContactAnniversary anniversary; |
410 QContactAnniversary anniversary; |
377 QDateTime dateTime = |
411 QDateTime dateTime = parseDateTime(property.value(), QLatin1String("yyyyMMdd")); |
378 parseDateTime(property.value(), QLatin1String("yyyyMMdd")); |
412 if (!dateTime.isValid()) |
|
413 return false; |
379 anniversary.setOriginalDate(dateTime.date()); |
414 anniversary.setOriginalDate(dateTime.date()); |
380 |
|
381 saveDetailWithContext(contact, &anniversary, extractContexts(property)); |
415 saveDetailWithContext(contact, &anniversary, extractContexts(property)); |
382 return true; |
416 return true; |
383 } |
417 } |
384 |
418 |
385 /*! |
419 /*! |
387 */ |
421 */ |
388 bool QVersitContactImporterPrivate::createBirthday( |
422 bool QVersitContactImporterPrivate::createBirthday( |
389 const QVersitProperty& property, QContact* contact) const |
423 const QVersitProperty& property, QContact* contact) const |
390 { |
424 { |
391 QContactBirthday bday; |
425 QContactBirthday bday; |
392 QDateTime dateTime = |
426 QDateTime dateTime = parseDateTime(property.value(), QLatin1String("yyyyMMdd")); |
393 parseDateTime(property.value(), QLatin1String("yyyyMMdd")); |
427 if (!dateTime.isValid()) |
|
428 return false; |
394 bday.setDate(dateTime.date()); |
429 bday.setDate(dateTime.date()); |
395 |
|
396 saveDetailWithContext(contact, &bday, extractContexts(property)); |
430 saveDetailWithContext(contact, &bday, extractContexts(property)); |
397 return true; |
431 return true; |
398 } |
432 } |
399 |
433 |
400 /*! |
434 /*! |
408 || variant.type() != QVariant::StringList) |
442 || variant.type() != QVariant::StringList) |
409 return false; |
443 return false; |
410 QStringList values = variant.toStringList(); |
444 QStringList values = variant.toStringList(); |
411 QStringList contexts = extractContexts(property); |
445 QStringList contexts = extractContexts(property); |
412 foreach(const QString& value, values) { |
446 foreach(const QString& value, values) { |
413 QContactNickname nickName; |
447 if (!value.isEmpty()) { |
414 nickName.setNickname(value); |
448 QContactNickname nickName; |
415 saveDetailWithContext(contact, &nickName, contexts); |
449 nickName.setNickname(value); |
|
450 saveDetailWithContext(contact, &nickName, contexts); |
|
451 } |
416 } |
452 } |
417 return true; |
453 return true; |
418 } |
454 } |
419 |
455 |
420 /*! |
456 /*! |
428 || variant.type() != QVariant::StringList) |
464 || variant.type() != QVariant::StringList) |
429 return false; |
465 return false; |
430 QStringList values = variant.toStringList(); |
466 QStringList values = variant.toStringList(); |
431 QStringList contexts = extractContexts(property); |
467 QStringList contexts = extractContexts(property); |
432 foreach(const QString& value, values) { |
468 foreach(const QString& value, values) { |
433 QContactTag tag; |
469 if (!value.isEmpty()) { |
434 tag.setTag(value); |
470 QContactTag tag; |
435 saveDetailWithContext(contact, &tag, contexts); |
471 tag.setTag(value); |
|
472 saveDetailWithContext(contact, &tag, contexts); |
|
473 } |
436 } |
474 } |
437 return true; |
475 return true; |
438 } |
476 } |
439 |
477 |
440 /*! |
478 /*! |
442 */ |
480 */ |
443 bool QVersitContactImporterPrivate::createOnlineAccount( |
481 bool QVersitContactImporterPrivate::createOnlineAccount( |
444 const QVersitProperty& property, QContact* contact) const |
482 const QVersitProperty& property, QContact* contact) const |
445 { |
483 { |
446 QContactOnlineAccount onlineAccount; |
484 QContactOnlineAccount onlineAccount; |
|
485 QString value(property.value()); |
|
486 if (value.isEmpty()) |
|
487 return false; |
447 onlineAccount.setAccountUri(property.value()); |
488 onlineAccount.setAccountUri(property.value()); |
448 if (property.name() == QLatin1String("X-SIP")) { |
489 if (property.name() == QLatin1String("X-SIP")) { |
449 QStringList subTypes = extractSubTypes(property); |
490 QStringList subTypes = extractSubTypes(property); |
450 if (subTypes.count() == 0) |
491 if (subTypes.isEmpty()) |
451 subTypes.append(QContactOnlineAccount::SubTypeSip); |
492 subTypes.append(QContactOnlineAccount::SubTypeSip); |
452 onlineAccount.setSubTypes(subTypes); |
493 onlineAccount.setSubTypes(subTypes); |
453 } |
494 } else if (property.name() == QLatin1String("X-IMPP") || |
454 else if (property.name() == QLatin1String("X-IMPP") || |
495 property.name() == QLatin1String("IMPP") || |
455 property.name() == QLatin1String("IMPP") || |
496 property.name() == QLatin1String("X-JABBER")) { |
456 property.name() == QLatin1String("X-JABBER")) { |
|
457 onlineAccount.setSubTypes(QContactOnlineAccount::SubTypeImpp); |
497 onlineAccount.setSubTypes(QContactOnlineAccount::SubTypeImpp); |
458 } |
|
459 else { |
|
460 // NOP |
|
461 } |
498 } |
462 |
499 |
463 saveDetailWithContext(contact, &onlineAccount, extractContexts(property)); |
500 saveDetailWithContext(contact, &onlineAccount, extractContexts(property)); |
464 return true; |
501 return true; |
465 } |
502 } |
520 QVariant variant = property.variantValue(); |
557 QVariant variant = property.variantValue(); |
521 if (property.valueType() != QVersitProperty::CompoundType |
558 if (property.valueType() != QVersitProperty::CompoundType |
522 || variant.type() != QVariant::StringList) |
559 || variant.type() != QVariant::StringList) |
523 return false; |
560 return false; |
524 QStringList values = variant.toStringList(); |
561 QStringList values = variant.toStringList(); |
525 geo.setLongitude(takeFirst(values).toDouble()); |
562 bool ok1; |
526 geo.setLatitude(takeFirst(values).toDouble()); |
563 geo.setLongitude(takeFirst(values).toDouble(&ok1)); |
527 |
564 bool ok2; |
528 saveDetailWithContext(contact, &geo, extractContexts(property)); |
565 geo.setLatitude(takeFirst(values).toDouble(&ok2)); |
529 return true; |
566 |
|
567 if (ok1 && ok2) { |
|
568 saveDetailWithContext(contact, &geo, extractContexts(property)); |
|
569 return true; |
|
570 } else { |
|
571 return false; |
|
572 } |
530 } |
573 } |
531 |
574 |
532 /*! |
575 /*! |
533 * Creates a QContactFamily from \a property |
576 * Creates a QContactFamily from \a property |
534 */ |
577 */ |
536 const QVersitProperty& property, QContact* contact) const |
579 const QVersitProperty& property, QContact* contact) const |
537 { |
580 { |
538 QString val = property.value(); |
581 QString val = property.value(); |
539 QContactFamily family = contact->detail<QContactFamily>(); |
582 QContactFamily family = contact->detail<QContactFamily>(); |
540 if (property.name() == QLatin1String("X-SPOUSE")) { |
583 if (property.name() == QLatin1String("X-SPOUSE")) { |
|
584 if (val.isEmpty()) |
|
585 return false; |
541 family.setSpouse(val); |
586 family.setSpouse(val); |
542 } else if (property.name() == QLatin1String("X-CHILDREN")) { |
587 } else if (property.name() == QLatin1String("X-CHILDREN")) { |
543 QVariant variant = property.variantValue(); |
588 QVariant variant = property.variantValue(); |
544 if (property.valueType() != QVersitProperty::ListType |
589 if (property.valueType() != QVersitProperty::ListType |
545 || variant.type() != QVariant::StringList) |
590 || variant.type() != QVariant::StringList) |
546 return false; |
591 return false; |
547 QStringList values = variant.toStringList(); |
592 QStringList values = variant.toStringList(); |
|
593 if (values.isEmpty()) |
|
594 return false; |
548 family.setChildren(values); |
595 family.setChildren(values); |
|
596 } else { |
|
597 return false; |
549 } |
598 } |
550 |
599 |
551 saveDetailWithContext(contact, &family, extractContexts(property)); |
600 saveDetailWithContext(contact, &family, extractContexts(property)); |
552 return true; |
601 return true; |
553 } |
602 } |
556 * Creates a simple name-value contact detail. |
605 * Creates a simple name-value contact detail. |
557 */ |
606 */ |
558 bool QVersitContactImporterPrivate::createNameValueDetail( |
607 bool QVersitContactImporterPrivate::createNameValueDetail( |
559 const QVersitProperty& property, QContact* contact) const |
608 const QVersitProperty& property, QContact* contact) const |
560 { |
609 { |
|
610 QString value(property.value()); |
|
611 if (value.isEmpty()) |
|
612 return false; |
561 QPair<QString,QString> nameAndValueType = |
613 QPair<QString,QString> nameAndValueType = |
562 mDetailMappings.value(property.name()); |
614 mDetailMappings.value(property.name()); |
563 if (nameAndValueType.first.isEmpty()) { |
615 if (nameAndValueType.first.isEmpty()) |
564 return false; |
616 return false; |
565 } |
617 |
566 QContactDetail detail(nameAndValueType.first); |
618 QContactDetail detail(nameAndValueType.first); |
567 detail.setValue(nameAndValueType.second, property.value()); |
619 detail.setValue(nameAndValueType.second, value); |
568 |
620 |
569 saveDetailWithContext(contact, &detail, extractContexts(property)); |
621 saveDetailWithContext(contact, &detail, extractContexts(property)); |
570 return true; |
622 return true; |
571 } |
623 } |
572 |
624 |
573 /*! |
625 /*! |
574 * Creates a simple name-value contact detail. |
626 * Find an existing QContactName and set the CustomLabel field on it |
575 */ |
627 */ |
576 bool QVersitContactImporterPrivate::createCustomLabel( |
628 bool QVersitContactImporterPrivate::createCustomLabel( |
577 const QVersitProperty& property, QContact* contact) const |
629 const QVersitProperty& property, QContact* contact) const |
578 { |
630 { |
579 QContactName name; |
631 QString label(property.value()); |
580 QContactName existingName = contact->detail<QContactName>(); |
632 if (!label.isEmpty()) { |
581 if (!existingName.isEmpty()) { |
633 QContactName name; |
582 name = existingName; |
634 QContactName existingName = contact->detail<QContactName>(); |
583 } |
635 if (!existingName.isEmpty()) { |
584 |
636 name = existingName; |
585 name.setCustomLabel(property.value()); |
637 } |
586 |
638 |
587 saveDetailWithContext(contact, &name, extractContexts(property)); |
639 name.setCustomLabel(property.value()); |
588 return true; |
640 |
|
641 saveDetailWithContext(contact, &name, extractContexts(property)); |
|
642 return true; |
|
643 } else { |
|
644 return false; |
|
645 } |
589 } |
646 } |
590 |
647 |
591 /*! |
648 /*! |
592 * Extracts the list of contexts from \a types |
649 * Extracts the list of contexts from \a types |
593 */ |
650 */ |
594 QStringList QVersitContactImporterPrivate::extractContexts( |
651 QStringList QVersitContactImporterPrivate::extractContexts( |
595 const QVersitProperty& property) const |
652 const QVersitProperty& property) const |
596 { |
653 { |
597 QStringList types = |
654 QStringList types = property.parameters().values(QLatin1String("TYPE")); |
598 property.parameters().values(QLatin1String("TYPE")); |
|
599 QStringList contexts; |
655 QStringList contexts; |
600 foreach (const QString& type, types) { |
656 foreach (const QString& type, types) { |
601 QString value = mContextMappings.value(type); |
657 QString value = mContextMappings.value(type.toUpper()); |
602 if (value.length() > 0) |
658 if (value.length() > 0) |
603 contexts.append(value); |
659 contexts.append(value); |
604 } |
660 } |
605 return contexts; |
661 return contexts; |
606 } |
662 } |
609 * Extracts the list of subtypes from \a property |
665 * Extracts the list of subtypes from \a property |
610 */ |
666 */ |
611 QStringList QVersitContactImporterPrivate::extractSubTypes( |
667 QStringList QVersitContactImporterPrivate::extractSubTypes( |
612 const QVersitProperty& property) const |
668 const QVersitProperty& property) const |
613 { |
669 { |
614 QStringList types = |
670 QStringList types = property.parameters().values(QLatin1String("TYPE")); |
615 property.parameters().values(QLatin1String("TYPE")); |
|
616 QStringList subTypes; |
671 QStringList subTypes; |
617 foreach (const QString& type, types) { |
672 foreach (const QString& type, types) { |
618 QString subType = mSubTypeMappings.value(type); |
673 QString subType = mSubTypeMappings.value(type.toUpper()); |
619 if (subType.length() > 0) |
674 if (subType.length() > 0) |
620 subTypes += subType; |
675 subTypes += subType; |
621 } |
676 } |
622 return subTypes; |
677 return subTypes; |
623 } |
678 } |
690 * Saves \a detail to the \a contact. Also sets the contexts to \a contexts if it is not empty. |
745 * Saves \a detail to the \a contact. Also sets the contexts to \a contexts if it is not empty. |
691 */ |
746 */ |
692 void QVersitContactImporterPrivate::saveDetailWithContext( |
747 void QVersitContactImporterPrivate::saveDetailWithContext( |
693 QContact* contact, QContactDetail* detail, const QStringList& contexts) const |
748 QContact* contact, QContactDetail* detail, const QStringList& contexts) const |
694 { |
749 { |
695 if (!contexts.isEmpty()) |
750 if (!contexts.isEmpty()) { |
696 detail->setContexts(contexts); |
751 detail->setContexts(contexts); |
|
752 } |
697 contact->saveDetail(detail); |
753 contact->saveDetail(detail); |
698 } |
754 } |
699 |
755 |
700 /*! Synthesize the display label from the name of the contact, or, failing that, the nickname of |
756 /*! Synthesize the display label from the name of the contact, or, failing that, the nickname of |
701 the contact, or failing that, the organisation of the contact. |
757 the contact, or failing that, the organisation of the contact. |