1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtVersit module of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include <qversitcontactexporter.h>
43
#include "qversitcontactexporter_p.h"
44
#include "qversitcontactimporter_p.h"
45
#include "qversitcontactsdefs_p.h"
46
#include "qversitutils_p.h"
49
#include <qcontactdetails.h>
50
#include "qversitcontacthandler.h"
51
#include "qversitcontactpluginloader_p.h"
56
QT_BEGIN_NAMESPACE_VERSIT
61
QVersitContactExporterPrivate::QVersitContactExporterPrivate(const QStringList& profiles) :
63
mDetailHandler2(NULL),
64
mDetailHandlerVersion(0),
65
mDefaultResourceHandler(new QVersitDefaultResourceHandler),
66
mResourceHandler(mDefaultResourceHandler)
69
int versitPropertyCount =
70
sizeof(versitContactDetailMappings)/sizeof(VersitContactDetailMapping);
71
// Put them in in reverse order so the entries at the top of the list take precedence
72
for (int i = versitPropertyCount-1; i >= 0; i--) {
73
mPropertyMappings.insert(
74
versitContactDetailMappings[i].detailType,
76
versitContactDetailMappings[i].detailField,
77
QLatin1String(versitContactDetailMappings[i].versitPropertyName)));
81
int contextCount = sizeof(versitContextMappings)/sizeof(VersitContextMapping);
82
for (int i=0; i < contextCount; i++) {
83
mContextMappings.insert(
84
versitContextMappings[i].contactContext,
85
QLatin1String(versitContextMappings[i].versitString));
89
int subTypeCount = sizeof(versitSubTypeMappings)/sizeof(VersitSubTypeMapping);
90
for (int i=0; i < subTypeCount; i++) {
91
mSubTypeMappings.insert(
92
QPair<QContactDetail::DetailType, int>(
93
versitSubTypeMappings[i].detailType, versitSubTypeMappings[i].contactSubType),
94
QLatin1String(versitSubTypeMappings[i].versitString));
96
mPluginDetailHandlers = QVersitContactPluginLoader::instance()->createContactHandlers(profiles);
102
QVersitContactExporterPrivate::~QVersitContactExporterPrivate()
104
delete mDefaultResourceHandler;
105
foreach (QVersitContactHandler* pluginHandler, mPluginDetailHandlers) {
106
delete pluginHandler;
112
* Export QT Contact into Versit Document.
114
void QVersitContactExporterPrivate::exportContact(
115
const QContact& contact,
116
QVersitDocument& document)
118
QList<QContactDetail> allDetails = contact.details();
119
foreach (const QContactDetail& detail, allDetails) {
121
&& mDetailHandler->preProcessDetail(contact, detail, &document))
124
QList<QVersitProperty> removedProperties;
125
QList<QVersitProperty> generatedProperties;
126
QSet<int> processedFields;
128
switch (detail.type()) {
129
case QContactDetail::TypeAddress:
130
encodeAddress(detail, &generatedProperties, &processedFields);
132
case QContactDetail::TypeAnniversary:
133
encodeAnniversary(detail, &generatedProperties, &processedFields);
135
case QContactDetail::TypeAvatar:
136
encodeAvatar(detail, &generatedProperties, &processedFields);
138
case QContactDetail::TypeBirthday:
139
encodeBirthDay(detail, &generatedProperties, &processedFields);
141
case QContactDetail::TypeDisplayLabel:
142
encodeDisplayLabel(detail, document, &removedProperties, &generatedProperties, &processedFields);
144
case QContactDetail::TypeEmailAddress:
145
encodeEmail(detail, &generatedProperties, &processedFields);
147
case QContactDetail::TypeExtendedDetail:
148
encodeExtendedDetail(detail, &generatedProperties, &processedFields);
150
case QContactDetail::TypeFamily:
151
encodeFamily(detail, &generatedProperties, &processedFields);
153
case QContactDetail::TypeFavorite:
154
encodeFavorite(detail, &generatedProperties, &processedFields);
156
case QContactDetail::TypeGender:
157
encodeGender(detail, &generatedProperties, &processedFields);
159
case QContactDetail::TypeGeoLocation:
160
encodeGeoLocation(detail, &generatedProperties, &processedFields);
162
case QContactDetail::TypeGuid:
163
encodeUid(detail, &generatedProperties, &processedFields);
165
case QContactDetail::TypeName:
166
encodeName(detail, document, &removedProperties, &generatedProperties, &processedFields);
168
case QContactDetail::TypeNickname:
169
encodeNickname(detail, document, &removedProperties, &generatedProperties, &processedFields);
171
case QContactDetail::TypeNote:
172
encodeNote(detail, &generatedProperties, &processedFields);
174
case QContactDetail::TypeOnlineAccount:
175
encodeOnlineAccount(detail, &generatedProperties, &processedFields);
177
case QContactDetail::TypeOrganization:
178
encodeOrganization(detail, &generatedProperties, &processedFields);
180
case QContactDetail::TypePhoneNumber:
181
encodePhoneNumber(detail, &generatedProperties, &processedFields);
183
case QContactDetail::TypeRingtone:
184
encodeRingtone(detail, &generatedProperties, &processedFields);
186
case QContactDetail::TypeTag:
187
encodeTag(detail, document, &removedProperties, &generatedProperties, &processedFields);
189
case QContactDetail::TypeTimestamp:
190
encodeRev(detail, &generatedProperties, &processedFields);
192
case QContactDetail::TypeUrl:
193
encodeUrl(detail, &generatedProperties, &processedFields);
195
case QContactDetail::TypeVersion:
196
encodeVersion(detail, &generatedProperties, &processedFields);
202
// run plugin handlers
203
foreach (QVersitContactExporterDetailHandlerV2* handler, mPluginDetailHandlers) {
204
handler->detailProcessed(contact, detail, document,
205
&processedFields, &removedProperties, &generatedProperties);
207
// run the v2 handler, if set
208
if (mDetailHandler2 && mDetailHandlerVersion > 1) {
209
mDetailHandler2->detailProcessed(contact, detail, document,
210
&processedFields, &removedProperties, &generatedProperties);
213
foreach(const QVersitProperty& property, removedProperties) {
214
document.removeProperty(property);
216
foreach(const QVersitProperty& property, generatedProperties) {
217
document.addProperty(property);
220
if (mDetailHandler && mDetailHandlerVersion == 1) {
221
mDetailHandler->postProcessDetail(contact, detail, !processedFields.isEmpty(), &document);
225
// run plugin handlers
226
foreach (QVersitContactExporterDetailHandlerV2* handler, mPluginDetailHandlers) {
227
handler->contactProcessed(contact, &document);
229
// run the v2 handler, if set
230
if (mDetailHandler2 && mDetailHandlerVersion > 1) {
231
mDetailHandler2->contactProcessed(contact, &document);
234
ensureDocumentContainsName(&document);
239
* Adds to \a document an empty "N" property if it doesn't already have one.
241
void QVersitContactExporterPrivate::ensureDocumentContainsName(QVersitDocument* document)
243
bool containsN = false;
244
foreach (const QVersitProperty& property, document->properties()) {
245
const QString& name = property.name();
246
if (name == QStringLiteral("N")) {
252
QVersitProperty nProperty;
253
nProperty.setValueType(QVersitProperty::CompoundType);
254
nProperty.setName(QStringLiteral("N"));
255
nProperty.setValue(QStringList() << QString() << QString()
256
<< QString() << QString() << QString());
257
document->addProperty(nProperty);
262
* Encode Contact Name Field Information into the Versit Document
264
void QVersitContactExporterPrivate::encodeName(
265
const QContactDetail& detail,
266
const QVersitDocument& document,
267
QList<QVersitProperty>* removedProperties,
268
QList<QVersitProperty>* generatedProperties,
269
QSet<int>* processedFields)
272
Q_UNUSED(removedProperties);
273
const QContactName &contactName = static_cast<const QContactName &>(detail);
274
if (!contactName.lastName().isEmpty()
275
|| !contactName.firstName().isEmpty()
276
|| !contactName.middleName().isEmpty()
277
|| !contactName.prefix().isEmpty()
278
|| !contactName.suffix().isEmpty()) {
279
QVersitProperty property;
280
property.setName(mPropertyMappings.value(detail.type()).second);
281
property.setValue(QStringList()
282
<< contactName.lastName()
283
<< contactName.firstName()
284
<< contactName.middleName()
285
<< contactName.prefix()
286
<< contactName.suffix());
287
property.setValueType(QVersitProperty::CompoundType);
288
*generatedProperties << property;
291
*processedFields << QContactName::FieldLastName
292
<< QContactName::FieldFirstName
293
<< QContactName::FieldMiddleName
294
<< QContactName::FieldPrefix
295
<< QContactName::FieldSuffix;
299
* Encode Phone Number Field Information into the Versit Document
301
void QVersitContactExporterPrivate::encodePhoneNumber(
302
const QContactDetail& detail,
303
QList<QVersitProperty>* generatedProperties,
304
QSet<int>* processedFields)
306
const QContactPhoneNumber &phoneNumber = static_cast<const QContactPhoneNumber &>(detail);
307
QList<int> subTypes = phoneNumber.subTypes();
308
QList<int> phoneNumberContextInt;
310
for (int i=0; i<phoneNumber.contexts().count(); i++)
311
phoneNumberContextInt << phoneNumber.contexts().at(i);
313
QVersitProperty property;
314
if (subTypes.contains(QContactPhoneNumber::SubTypeAssistant))
315
property.setName(QStringLiteral("X-ASSISTANT-TEL"));
317
property.setName(QStringLiteral("TEL"));
318
encodeParameters(property, detail.type(), phoneNumberContextInt, subTypes);
319
property.setValue(phoneNumber.number());
320
*generatedProperties << property;
321
*processedFields << QContactPhoneNumber::FieldContext
322
<< QContactPhoneNumber::FieldSubTypes
323
<< QContactPhoneNumber::FieldNumber;
327
* Encode Email Field Information into the Versit Document
329
void QVersitContactExporterPrivate::encodeEmail(
330
const QContactDetail& detail,
331
QList<QVersitProperty>* generatedProperties,
332
QSet<int>* processedFields)
334
const QContactEmailAddress &emailAddress = static_cast<const QContactEmailAddress &>(detail);
335
QList<int> emailAddressContextInt;
337
for (int i=0; i<emailAddress.contexts().count(); i++)
338
emailAddressContextInt << emailAddress.contexts().at(i);
340
QVersitProperty property;
341
property.setName(mPropertyMappings.value(detail.type()).second);
342
encodeParameters(property, detail.type(), emailAddressContextInt);
343
property.setValue(emailAddress.emailAddress());
344
*generatedProperties << property;
345
*processedFields << QContactEmailAddress::FieldContext
346
<< QContactEmailAddress::FieldEmailAddress;
350
* Encode Address Field Information into the Versit Document
352
void QVersitContactExporterPrivate::encodeAddress(
353
const QContactDetail& detail,
354
QList<QVersitProperty>* generatedProperties,
355
QSet<int>* processedFields)
357
const QContactAddress &address = static_cast<const QContactAddress &>(detail);
358
QList<int> addressContextInt;
360
for (int i=0; i<address.contexts().count(); i++)
361
addressContextInt << address.contexts().at(i);
363
QVersitProperty property;
364
property.setName(mPropertyMappings.value(detail.type()).second);
365
encodeParameters(property, detail.type(), addressContextInt, address.subTypes());
366
property.setValue(QStringList()
367
<< address.postOfficeBox()
368
<< QString() // Leave out the extended address field
370
<< address.locality()
372
<< address.postcode()
373
<< address.country());
374
property.setValueType(QVersitProperty::CompoundType);
375
*generatedProperties << property;
376
*processedFields << QContactAddress::FieldContext
377
<< QContactAddress::FieldSubTypes
378
<< QContactAddress::FieldPostOfficeBox
379
<< QContactAddress::FieldStreet
380
<< QContactAddress::FieldLocality
381
<< QContactAddress::FieldRegion
382
<< QContactAddress::FieldPostcode
383
<< QContactAddress::FieldCountry;
387
* Encode URL Field Information into the Versit Document
389
void QVersitContactExporterPrivate::encodeUrl(
390
const QContactDetail& detail,
391
QList<QVersitProperty>* generatedProperties,
392
QSet<int>* processedFields)
394
const QContactUrl &contactUrl = static_cast<const QContactUrl &>(detail);
395
QList<int> contactUrlContextInt;
397
for (int i=0; i<contactUrl.contexts().count(); i++)
398
contactUrlContextInt << contactUrl.contexts().at(i);
400
QVersitProperty property;
401
property.setName(mPropertyMappings.value(detail.type()).second);
402
encodeParameters(property, detail.type(), contactUrlContextInt);
403
// The vCard specifications do not define any TYPEs for URL property.
404
// No need to try to convert the subtypes to TYPEs.
405
property.setValue(contactUrl.url());
406
*generatedProperties << property;
407
*processedFields << QContactUrl::FieldContext
408
<< QContactUrl::FieldUrl;
412
* Encode Uid Field Information into the Versit Document
414
void QVersitContactExporterPrivate::encodeUid(
415
const QContactDetail& detail,
416
QList<QVersitProperty>* generatedProperties,
417
QSet<int>* processedFields)
419
const QContactGuid &uid = static_cast<const QContactGuid &>(detail);
420
QVersitProperty property;
421
property.setName(mPropertyMappings.value(detail.type()).second);
422
property.setValue(uid.guid());
423
*generatedProperties << property;
424
*processedFields << QContactGuid::FieldGuid;
428
* Encode REV Field Information into the Versit Document
430
void QVersitContactExporterPrivate::encodeRev(
431
const QContactDetail& detail,
432
QList<QVersitProperty>* generatedProperties,
433
QSet<int>* processedFields)
435
const QContactTimestamp &rev = static_cast<const QContactTimestamp &>(detail);
437
QVersitProperty property;
438
property.setName(mPropertyMappings.value(detail.type()).second);
439
if ( rev.lastModified().toString(Qt::ISODate).size() ) {
440
if ( rev.lastModified().timeSpec() == Qt::UTC ) {
441
value = rev.lastModified().toString(Qt::ISODate);
442
if( !value.endsWith(QLatin1Char('Z'), Qt::CaseInsensitive) ) {
443
value += QLatin1Char('Z');
447
value = rev.lastModified().toString(Qt::ISODate);
449
property.setValue(value);
450
*generatedProperties << property;
451
*processedFields << QContactTimestamp::FieldModificationTimestamp;
452
} else if ( rev.created().toString(Qt::ISODate).size()) {
453
if ( rev.created().timeSpec() == Qt::UTC ) {
454
value = rev.created().toString(Qt::ISODate);
455
if( !value.endsWith(QLatin1Char('Z'), Qt::CaseInsensitive) ) {
456
value += QLatin1Char('Z');
460
value = rev.created().toString(Qt::ISODate);
462
property.setValue(value);
463
*generatedProperties << property;
464
*processedFields << QContactTimestamp::FieldCreationTimestamp;
469
* Encode Contact Version Field Information into the Versit Document
471
void QVersitContactExporterPrivate::encodeVersion(
472
const QContactDetail& detail,
473
QList<QVersitProperty>* generatedProperties,
474
QSet<int>* processedFields)
476
const QContactVersion &version = static_cast<const QContactVersion &>(detail);
477
QVersitProperty property;
478
property.setName(mPropertyMappings.value(detail.type()).second);
479
QStringList values(QString::number(version.sequenceNumber()));
480
values.append(QString::fromLocal8Bit(version.extendedVersion()));
481
property.setValue(values);
482
property.setValueType(QVersitProperty::CompoundType);
483
*generatedProperties << property;
484
*processedFields << QContactVersion::FieldSequenceNumber
485
<< QContactVersion::FieldExtendedVersion;
489
* Encode BirthDay Field Information into the Versit Document
491
void QVersitContactExporterPrivate::encodeBirthDay(
492
const QContactDetail& detail,
493
QList<QVersitProperty>* generatedProperties,
494
QSet<int>* processedFields)
496
const QContactBirthday &bday = static_cast<const QContactBirthday &>(detail);
497
QVersitProperty property;
498
property.setName(mPropertyMappings.value(detail.type()).second);
499
QVariant variant = bday.value(QContactBirthday::FieldBirthday);
501
if (variant.type() == QVariant::Date) {
502
value = variant.toDate().toString(Qt::ISODate);
503
} else if (variant.type() == QVariant::DateTime) {
504
value = variant.toDateTime().toString(Qt::ISODate);
508
property.setValue(value);
509
*generatedProperties << property;
510
*processedFields << QContactBirthday::FieldBirthday;
514
* Encodes displaylabel property information into the Versit Document
516
void QVersitContactExporterPrivate::encodeDisplayLabel(
517
const QContactDetail &detail,
518
const QVersitDocument& document,
519
QList<QVersitProperty>* removedProperties,
520
QList<QVersitProperty>* generatedProperties,
521
QSet<int>* processedFields)
523
const QContactDisplayLabel &displaylabelDetail = static_cast<const QContactDisplayLabel &>(detail);
524
QVersitProperty property =
525
VersitUtils::takeProperty(document, QStringLiteral("FN"), removedProperties);
526
property.setName(QStringLiteral("FN"));
527
QStringList value(property.variantValue().toStringList());
528
value.append(displaylabelDetail.label());
529
property.setValue(value);
530
*generatedProperties << property;
531
*processedFields << QContactDisplayLabel::FieldLabel;
535
* Encode Comment i.e. Note Field Information into the Versit Document
537
void QVersitContactExporterPrivate::encodeNote(
538
const QContactDetail& detail,
539
QList<QVersitProperty>* generatedProperties,
540
QSet<int>* processedFields)
542
const QContactNote &contactNote = static_cast<const QContactNote &>(detail);
543
QVersitProperty property;
544
property.setName(mPropertyMappings.value(detail.type()).second);
545
property.setValue(contactNote.note());
546
*generatedProperties << property;
547
*processedFields << QContactNote::FieldNote;
551
* Encode Geo Prpoperties Field Information into the Versit Document
553
void QVersitContactExporterPrivate::encodeGeoLocation(
554
const QContactDetail& detail,
555
QList<QVersitProperty>* generatedProperties,
556
QSet<int>* processedFields)
558
const QContactGeoLocation &geoLocation = static_cast<const QContactGeoLocation &>(detail);
559
QVersitProperty property;
560
property.setName(mPropertyMappings.value(detail.type()).second);
561
property.setValue(QStringList() << QString::number(geoLocation.latitude())
562
<< QString::number(geoLocation.longitude()));
563
property.setValueType(QVersitProperty::CompoundType);
564
*generatedProperties << property;
565
*processedFields << QContactGeoLocation::FieldLongitude
566
<< QContactGeoLocation::FieldLatitude;
570
* Encode organization properties to the versit document
572
void QVersitContactExporterPrivate::encodeOrganization(
573
const QContactDetail& detail,
574
QList<QVersitProperty>* generatedProperties,
575
QSet<int>* processedFields)
577
const QContactOrganization &organization = static_cast<const QContactOrganization &>(detail);
578
if (organization.title().length() > 0) {
579
QVersitProperty property;
580
property.setName(QStringLiteral("TITLE"));
581
property.setValue(organization.title());
582
*generatedProperties << property;
583
*processedFields << QContactOrganization::FieldTitle;
585
if (organization.name().length() > 0 || organization.department().size() > 0) {
586
QVersitProperty property;
587
property.setName(QStringLiteral("ORG"));
588
QStringList values(organization.name());
589
values.append(organization.department());
590
property.setValue(values);
591
property.setValueType(QVersitProperty::CompoundType);
592
*generatedProperties << property;
593
*processedFields << QContactOrganization::FieldName
594
<< QContactOrganization::FieldDepartment;
596
if (organization.logoUrl().isValid()) {
597
QVersitProperty property;
598
if (encodeContentFromFile(organization.logoUrl().toString(), property)) {
599
property.setName(QStringLiteral("LOGO"));
600
*generatedProperties << property;
601
*processedFields << QContactOrganization::FieldLogoUrl;
604
if (organization.assistantName().length() > 0) {
605
QVersitProperty property;
606
property.setName(QStringLiteral("X-ASSISTANT"));
607
property.setValue(organization.assistantName());
608
*generatedProperties << property;
609
*processedFields << QContactOrganization::FieldAssistantName;
612
if (organization.role().length() > 0) {
613
QVersitProperty property;
614
property.setName(QStringLiteral("ROLE"));
615
property.setValue(organization.role());
616
*generatedProperties << property;
617
*processedFields << QContactOrganization::FieldRole;
621
void QVersitContactExporterPrivate::encodeRingtone(
622
const QContactDetail &detail,
623
QList<QVersitProperty>* generatedProperties,
624
QSet<int>* processedFields)
626
const QContactRingtone &ringtone = static_cast<const QContactRingtone &>(detail);
627
QVersitProperty property;
628
property.setName(mPropertyMappings.value(detail.type()).second);
629
QUrl audioUrl(ringtone.audioRingtoneUrl());
631
if (!audioUrl.scheme().isEmpty() && !audioUrl.host().isEmpty() &&
632
audioUrl.scheme() != QStringLiteral("file")) {
633
property.insertParameter(QStringLiteral("VALUE"), QStringLiteral("URL"));
634
property.setValue(audioUrl.toString());
635
*generatedProperties << property;
636
*processedFields << QContactRingtone::FieldAudioRingtoneUrl;
638
} else if (encodeContentFromFile(ringtone.audioRingtoneUrl().toLocalFile(), property)) {
639
*generatedProperties << property;
640
*processedFields << QContactRingtone::FieldAudioRingtoneUrl;
645
* Encode avatar URIs into the Versit Document
647
void QVersitContactExporterPrivate::encodeAvatar(
648
const QContactDetail &detail,
649
QList<QVersitProperty>* generatedProperties,
650
QSet<int>* processedFields)
652
QVersitProperty property;
653
property.setName(QStringLiteral("PHOTO"));
654
const QContactAvatar &contactAvatar = static_cast<const QContactAvatar &>(detail);
655
QUrl imageUrl(contactAvatar.imageUrl());
656
// XXX: fix up this mess: checking the scheme here and in encodeContentFromFile,
657
// organisation logo and ringtone are QStrings but avatar is a QUrl
658
if (!imageUrl.scheme().isEmpty()
659
&& !imageUrl.host().isEmpty()
660
&& imageUrl.scheme() != QStringLiteral("file")) {
661
property.insertParameter(QStringLiteral("VALUE"), QStringLiteral("URL"));
662
property.setValue(imageUrl.toString());
663
*generatedProperties << property;
664
*processedFields << QContactAvatar::FieldImageUrl;
666
if (encodeContentFromFile(contactAvatar.imageUrl().toLocalFile(), property)) {
667
*generatedProperties << property;
668
*processedFields << QContactAvatar::FieldImageUrl;
674
* Encode gender property information into Versit Document
676
void QVersitContactExporterPrivate::encodeGender(
677
const QContactDetail &detail,
678
QList<QVersitProperty>* generatedProperties,
679
QSet<int>* processedFields)
681
const QContactGender &gender = static_cast<const QContactGender &>(detail);
682
if (!gender.gender())
685
QVersitProperty property;
686
property.setName(mPropertyMappings.value(detail.type()).second);
687
switch (gender.gender()) {
688
case QContactGender::GenderMale:
689
property.setValue(QStringLiteral("Male"));
691
case QContactGender::GenderFemale:
692
property.setValue(QStringLiteral("Female"));
694
case QContactGender::GenderUnspecified:
695
property.setValue(QStringLiteral("Unspecified"));
698
// May only happen if new gender values are added to QContactGender
699
// without adding them support above.
700
qWarning() << "Trying to encode unknown gender value.";
703
*generatedProperties << property;
704
*processedFields << QContactGender::FieldGender;
708
* Encodes nickname property information into the Versit Document
710
void QVersitContactExporterPrivate::encodeNickname(
711
const QContactDetail &detail,
712
const QVersitDocument& document,
713
QList<QVersitProperty>* removedProperties,
714
QList<QVersitProperty>* generatedProperties,
715
QSet<int>* processedFields)
717
const QContactNickname &nicknameDetail = static_cast<const QContactNickname &>(detail);
718
QVersitProperty property =
719
VersitUtils::takeProperty(document, QStringLiteral("X-NICKNAME"), removedProperties);
720
property.setName(QStringLiteral("X-NICKNAME"));
721
QStringList value(property.variantValue().toStringList());
722
value.append(nicknameDetail.nickname());
723
property.setValue(value);
724
property.setValueType(QVersitProperty::ListType);
725
*generatedProperties << property;
726
*processedFields << QContactNickname::FieldNickname;
730
* Encodes a contact tag into the Versit Document
732
void QVersitContactExporterPrivate::encodeTag(
733
const QContactDetail &detail,
734
const QVersitDocument& document,
735
QList<QVersitProperty>* removedProperties,
736
QList<QVersitProperty>* generatedProperties,
737
QSet<int>* processedFields)
739
const QContactTag &tagDetail = static_cast<const QContactTag &>(detail);
740
QVersitProperty property =
741
VersitUtils::takeProperty(document, QStringLiteral("CATEGORIES"), removedProperties);
742
property.setName(QStringLiteral("CATEGORIES"));
743
QStringList value(property.variantValue().toStringList());
744
value.append(tagDetail.tag());
745
property.setValue(value);
746
property.setValueType(QVersitProperty::ListType);
747
*generatedProperties << property;
748
*processedFields << QContactTag::FieldTag;
752
* Encode anniversary information into Versit Document
754
void QVersitContactExporterPrivate::encodeAnniversary(
755
const QContactDetail &detail,
756
QList<QVersitProperty>* generatedProperties,
757
QSet<int>* processedFields)
759
const QContactAnniversary &anniversary = static_cast<const QContactAnniversary &>(detail);
760
QVersitProperty property;
761
property.setName(mPropertyMappings.value(detail.type()).second);
762
property.setValue(anniversary.originalDate().toString(Qt::ISODate));
763
*generatedProperties << property;
764
*processedFields << QContactAnniversary::FieldOriginalDate;
768
* Encode online account information into the Versit Document
770
void QVersitContactExporterPrivate::encodeOnlineAccount(
771
const QContactDetail &detail,
772
QList<QVersitProperty>* generatedProperties,
773
QSet<int>* processedFields)
775
const QContactOnlineAccount &onlineAccount = static_cast<const QContactOnlineAccount &>(detail);
776
QList<int> subTypes = onlineAccount.subTypes();
778
QContactOnlineAccount::Protocol protocol = onlineAccount.protocol();
780
QString propertyName;
782
if (protocol == QContactOnlineAccount::ProtocolJabber) {
783
propertyName = QStringLiteral("X-JABBER");
784
} else if (protocol == QContactOnlineAccount::ProtocolAim) {
785
propertyName = QStringLiteral("X-AIM");
786
} else if (protocol == QContactOnlineAccount::ProtocolIcq) {
787
propertyName = QStringLiteral("X-ICQ");
788
} else if (protocol == QContactOnlineAccount::ProtocolMsn) {
789
propertyName = QStringLiteral("X-MSN");
790
} else if (protocol == QContactOnlineAccount::ProtocolQq) {
791
propertyName = QStringLiteral("X-QQ");
792
} else if (protocol == QContactOnlineAccount::ProtocolYahoo) {
793
propertyName = QStringLiteral("X-YAHOO");
794
} else if (protocol == QContactOnlineAccount::ProtocolSkype) {
795
propertyName = QStringLiteral("X-SKYPE");
796
} else if (subTypes.contains(QContactOnlineAccount::SubTypeSip) ||
797
subTypes.contains(QContactOnlineAccount::SubTypeSipVoip) ||
798
subTypes.contains(QContactOnlineAccount::SubTypeVideoShare)) {
799
propertyName = QStringLiteral("X-SIP");
800
} else if (subTypes.contains(QContactOnlineAccount::SubTypeImpp)) {
801
propertyName = QStringLiteral("X-IMPP");
804
if (!propertyName.isEmpty()) {
805
QList<int> onlineAccountContextInt;
807
for (int i=0; i<onlineAccount.contexts().count(); i++)
808
onlineAccountContextInt << onlineAccount.contexts().at(i);
810
QVersitProperty property;
811
encodeParameters(property, detail.type(), onlineAccountContextInt, subTypes);
812
property.setName(propertyName);
813
property.setValue(onlineAccount.accountUri());
814
*generatedProperties << property;
815
*processedFields << QContactOnlineAccount::FieldSubTypes
816
<< QContactOnlineAccount::FieldAccountUri;
821
* Encode family versit property if its supported in Versit Document
823
void QVersitContactExporterPrivate::encodeFamily(
824
const QContactDetail &detail,
825
QList<QVersitProperty>* generatedProperties,
826
QSet<int>* processedFields)
828
const QContactFamily &family = static_cast<const QContactFamily &>(detail);
830
if (family.spouse().size()) {
831
QVersitProperty property;
832
property.setName(QStringLiteral("X-SPOUSE"));
833
property.setValue(family.spouse());
834
*generatedProperties << property;
835
*processedFields << QContactFamily::FieldSpouse;
838
if (family.children().size()) {
839
QVersitProperty property;
840
property.setName(QStringLiteral("X-CHILDREN"));
841
property.setValue(family.children());
842
property.setValueType(QVersitProperty::ListType);
843
*generatedProperties << property;
844
*processedFields << QContactFamily::FieldChildren;
849
* Encode favorite versit property if its supported in Versit Document
851
void QVersitContactExporterPrivate::encodeFavorite(
852
const QContactDetail &detail,
853
QList<QVersitProperty>* generatedProperties,
854
QSet<int>* processedFields)
856
const QContactFavorite &favorite = static_cast<const QContactFavorite &>(detail);
857
QVersitProperty property;
858
property.setName(mPropertyMappings.value(detail.type()).second);
859
QString isFavorite = favorite.isFavorite() ? QStringLiteral("true") : QStringLiteral("false");
860
property.setValue(QStringList() << isFavorite
861
<< QString::number(favorite.index()));
862
property.setValueType(QVersitProperty::CompoundType);
863
*generatedProperties << property;
864
*processedFields << QContactFavorite::FieldFavorite
865
<< QContactFavorite::FieldIndex;
869
* Encode extended detail into the Versit Document
871
void QVersitContactExporterPrivate::encodeExtendedDetail(
872
const QContactDetail &detail,
873
QList<QVersitProperty>* generatedProperties,
874
QSet<int>* processedFields)
876
const QContactExtendedDetail &extendedDetail =
877
static_cast<const QContactExtendedDetail &>(detail);
878
QVersitProperty property;
879
property.setName(mPropertyMappings.value(extendedDetail.type()).second);
881
if (VersitUtils::convertToJson(extendedDetail.data(), &dataAsJson)) {
882
property.setValue(QStringList() << extendedDetail.name() << dataAsJson);
884
qWarning() << Q_FUNC_INFO << "Failed to export an extended detail";
887
property.setValueType(QVersitProperty::CompoundType);
888
*generatedProperties << property;
889
*processedFields << QContactExtendedDetail::FieldName
890
<< QContactExtendedDetail::FieldData;
894
* Check if \a resourceIdentifier represents a valid remote resource
896
bool QVersitContactExporterPrivate::isValidRemoteUrl(
897
const QString& resourceIdentifier)
899
QUrl remoteResource(resourceIdentifier);
900
if ((!remoteResource.scheme().isEmpty() &&
901
!remoteResource.host().isEmpty()) ||
902
resourceIdentifier.contains(QStringLiteral("www."), Qt::CaseInsensitive))
908
* Encode parameters to \a property
910
void QVersitContactExporterPrivate::encodeParameters(
911
QVersitProperty& property,
912
const QContactDetail::DetailType detailType,
913
const QList<int>& contexts,
914
const QList<int>& subTypes)
916
QList<int> contextsList(contexts); // Contexts should be encoded first
917
QList<int> subtypesList(subTypes); // Contexts should be encoded first
919
while (!contextsList.isEmpty()) {
920
int value = contextsList.takeLast();
921
QString mappedValue = mContextMappings.value(value);
922
if (mappedValue.length() > 0) {
923
// QVersitProperty::addParameter inserts into beginning.
924
// This is why the last value is taken from the list
925
property.insertParameter(QStringLiteral("TYPE"),mappedValue);
929
while (!subtypesList.isEmpty()) {
930
int value = subtypesList.takeLast();
931
QString mappedValue = mSubTypeMappings.value(QPair<QContactDetail::DetailType, int>(
933
if (mappedValue.length() > 0) {
934
// QVersitProperty::addParameter inserts into beginning.
935
// This is why the last value is taken from the list
936
property.insertParameter(QStringLiteral("TYPE"),mappedValue);
942
* Encode embedded content from the given \a resourcePath into \a property.
944
bool QVersitContactExporterPrivate::encodeContentFromFile(const QString& resourcePath,
945
QVersitProperty& property)
947
bool encodeContent = false;
949
QByteArray imageData;
951
if (isValidRemoteUrl( resourcePath )) {
952
encodeContent = true;
953
value.setValue(resourcePath);
954
property.insertParameter(QStringLiteral("VALUE"), QStringLiteral("uri"));
955
} else if (mResourceHandler
956
&& mResourceHandler->loadResource(resourcePath, &imageData, &mimeType)) {
957
value.setValue(imageData);
958
if (!mimeType.isEmpty()) {
959
// If mimeType is (eg.) "image/jpeg", set type parameter to "JPEG"
960
int slashIndex = mimeType.indexOf(QLatin1Char('/'));
962
property.insertParameter(QStringLiteral("TYPE"),
963
mimeType.remove(0, slashIndex+1).toUpper());
965
encodeContent = true;
967
// The file doesn't exist. Don't encode the path to a local file.
969
property.setValue(value);
970
return encodeContent;
973
QT_END_NAMESPACE_VERSIT