|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qversitcontactexporter.h" |
|
43 #include "qversitcontactexporter_p.h" |
|
44 #include "qversitdefs_p.h" |
|
45 #include "versitutils_p.h" |
|
46 #include "qmobilityglobal.h" |
|
47 |
|
48 #include <qcontact.h> |
|
49 #include <qcontactdetail.h> |
|
50 #include <qcontactname.h> |
|
51 #include <qcontactemailaddress.h> |
|
52 #include <qcontactphonenumber.h> |
|
53 #include <qcontactaddress.h> |
|
54 #include <qcontacturl.h> |
|
55 #include <qcontactguid.h> |
|
56 #include <qcontactorganization.h> |
|
57 #include <qcontacttimestamp.h> |
|
58 #include <qcontactbirthday.h> |
|
59 #include <qcontactnote.h> |
|
60 #include <qcontactgeolocation.h> |
|
61 #include <qcontactavatar.h> |
|
62 #include <qcontactgender.h> |
|
63 #include <qcontactnickname.h> |
|
64 #include <qcontactanniversary.h> |
|
65 #include <qcontactonlineaccount.h> |
|
66 #include <qcontactfamily.h> |
|
67 #include <qcontactdisplaylabel.h> |
|
68 #include <qcontactthumbnail.h> |
|
69 |
|
70 #include <QUrl> |
|
71 #include <QBuffer> |
|
72 |
|
73 QTM_USE_NAMESPACE |
|
74 |
|
75 /*! |
|
76 * Constructor. |
|
77 */ |
|
78 QVersitContactExporterPrivate::QVersitContactExporterPrivate() : |
|
79 mDetailHandler(NULL), |
|
80 mDetailHandler2(NULL), |
|
81 mDetailHandlerVersion(0), |
|
82 mDefaultResourceHandler(new QVersitDefaultResourceHandler), |
|
83 mResourceHandler(mDefaultResourceHandler), |
|
84 mVersitType(QVersitDocument::InvalidType) |
|
85 { |
|
86 // Detail mappings |
|
87 int versitPropertyCount = |
|
88 sizeof(versitContactDetailMappings)/sizeof(VersitContactDetailMapping); |
|
89 for (int i=0; i < versitPropertyCount; i++) { |
|
90 mPropertyMappings.insert( |
|
91 QLatin1String(versitContactDetailMappings[i].contactDetailDefinitionName), |
|
92 QLatin1String(versitContactDetailMappings[i].versitPropertyName)); |
|
93 } |
|
94 |
|
95 // Contexts mappings |
|
96 int contextCount = sizeof(versitContextMappings)/sizeof(VersitMapping); |
|
97 for (int i=0; i < contextCount; i++) { |
|
98 mParameterMappings.insert( |
|
99 QLatin1String(versitContextMappings[i].contactString), |
|
100 QLatin1String(versitContextMappings[i].versitString)); |
|
101 } |
|
102 |
|
103 // Subtypes mappings |
|
104 int subTypeCount = sizeof(versitSubTypeMappings)/sizeof(VersitMapping); |
|
105 for (int i=0; i < subTypeCount; i++) { |
|
106 mParameterMappings.insert( |
|
107 QLatin1String(versitSubTypeMappings[i].contactString), |
|
108 QLatin1String(versitSubTypeMappings[i].versitString)); |
|
109 } |
|
110 } |
|
111 |
|
112 /*! |
|
113 * Destructor. |
|
114 */ |
|
115 QVersitContactExporterPrivate::~QVersitContactExporterPrivate() |
|
116 { |
|
117 delete mDefaultResourceHandler; |
|
118 } |
|
119 |
|
120 |
|
121 /*! |
|
122 * Export QT Contact into Versit Document. |
|
123 */ |
|
124 bool QVersitContactExporterPrivate::exportContact( |
|
125 const QContact& contact, |
|
126 QVersitDocument& document, |
|
127 QVersitContactExporter::Error* error) |
|
128 { |
|
129 mVersitType = document.type(); |
|
130 QList<QContactDetail> allDetails = contact.details(); |
|
131 if (allDetails.isEmpty()) { |
|
132 *error = QVersitContactExporter::EmptyContactError; |
|
133 return false; |
|
134 } |
|
135 for (int i = 0; i < allDetails.size(); i++) { |
|
136 QContactDetail detail = allDetails.at(i); |
|
137 |
|
138 // If the custom detail handler handles it, we don't have to. |
|
139 if (mDetailHandler |
|
140 && mDetailHandler->preProcessDetail(contact, detail, &document)) |
|
141 continue; |
|
142 |
|
143 QList<QVersitProperty> removedProperties; |
|
144 QList<QVersitProperty> generatedProperties; |
|
145 QSet<QString> processedFields; |
|
146 |
|
147 if (detail.definitionName() == QContactName::DefinitionName) { |
|
148 encodeName(detail, document, &removedProperties, &generatedProperties, &processedFields); |
|
149 } else if (detail.definitionName() == QContactPhoneNumber::DefinitionName) { |
|
150 encodePhoneNumber(detail, &generatedProperties, &processedFields); |
|
151 } else if (detail.definitionName() == QContactEmailAddress::DefinitionName) { |
|
152 encodeEmail(detail, &generatedProperties, &processedFields); |
|
153 } else if (detail.definitionName() == QContactAddress::DefinitionName) { |
|
154 encodeAddress(detail, &generatedProperties, &processedFields); |
|
155 } else if (detail.definitionName() == QContactGuid::DefinitionName) { |
|
156 encodeUid(detail, &generatedProperties, &processedFields); |
|
157 } else if (detail.definitionName() == QContactUrl::DefinitionName) { |
|
158 encodeUrl(detail, &generatedProperties, &processedFields); |
|
159 } else if (detail.definitionName() == QContactTimestamp::DefinitionName) { |
|
160 encodeRev(detail, &generatedProperties, &processedFields); |
|
161 } else if (detail.definitionName() == QContactBirthday::DefinitionName) { |
|
162 encodeBirthDay(detail, &generatedProperties, &processedFields); |
|
163 } else if (detail.definitionName() == QContactGeoLocation::DefinitionName) { |
|
164 encodeGeoLocation(detail, &generatedProperties, &processedFields); |
|
165 } else if (detail.definitionName() == QContactNote::DefinitionName) { |
|
166 encodeNote(detail, &generatedProperties, &processedFields); |
|
167 } else if (detail.definitionName() == QContactOrganization::DefinitionName) { |
|
168 encodeOrganization(detail, &generatedProperties, &processedFields); |
|
169 } else if (detail.definitionName() == QContactRingtone::DefinitionName) { |
|
170 encodeRingtone(detail, &generatedProperties, &processedFields); |
|
171 } else if (detail.definitionName() == QContactThumbnail::DefinitionName) { |
|
172 encodeThumbnail(detail, &generatedProperties, &processedFields); |
|
173 } else if (detail.definitionName() == QContactAvatar::DefinitionName){ |
|
174 encodeAvatar(detail, &generatedProperties, &processedFields); |
|
175 } else if (detail.definitionName() == QContactAnniversary::DefinitionName) { |
|
176 encodeAnniversary(detail, &generatedProperties, &processedFields); |
|
177 } else if (detail.definitionName() == QContactNickname::DefinitionName) { |
|
178 encodeNickname(detail, document, &removedProperties, &generatedProperties, &processedFields); |
|
179 } else if (detail.definitionName() == QContactTag::DefinitionName) { |
|
180 encodeTag(detail, document, &removedProperties, &generatedProperties, &processedFields); |
|
181 } else if (detail.definitionName() == QContactGender::DefinitionName) { |
|
182 encodeGender(detail, &generatedProperties, &processedFields); |
|
183 } else if (detail.definitionName() == QContactOnlineAccount::DefinitionName) { |
|
184 encodeOnlineAccount(detail, &generatedProperties, &processedFields); |
|
185 } else if (detail.definitionName() == QContactFamily::DefinitionName) { |
|
186 encodeFamily(detail, &generatedProperties, &processedFields); |
|
187 } else if (detail.definitionName() == QContactDisplayLabel::DefinitionName) { |
|
188 encodeDisplayLabel(detail, document, &removedProperties, &generatedProperties, &processedFields); |
|
189 } |
|
190 |
|
191 if (mDetailHandler2 && mDetailHandlerVersion > 1) { |
|
192 mDetailHandler2->detailProcessed(contact, detail, processedFields, document, |
|
193 &removedProperties, &generatedProperties); |
|
194 } |
|
195 |
|
196 foreach(const QVersitProperty& property, removedProperties) { |
|
197 document.removeProperty(property); |
|
198 } |
|
199 foreach(const QVersitProperty& property, generatedProperties) { |
|
200 document.addProperty(property); |
|
201 } |
|
202 |
|
203 if (mDetailHandler && mDetailHandlerVersion == 1) { |
|
204 mDetailHandler->postProcessDetail(contact, detail, !processedFields.isEmpty(), &document); |
|
205 } |
|
206 } |
|
207 |
|
208 if (mDetailHandler2 && mDetailHandlerVersion > 1) { |
|
209 mDetailHandler2->contactProcessed(contact, &document); |
|
210 } |
|
211 |
|
212 // Search through the document for FN or N properties. This will find it even if it was added |
|
213 // by a detail handler. |
|
214 if (!documentContainsName(document)) { |
|
215 *error = QVersitContactExporter::NoNameError; |
|
216 return false; |
|
217 } |
|
218 return true; |
|
219 } |
|
220 |
|
221 /*! |
|
222 * Returns true if and only if \a document has a "FN" or "N" property. |
|
223 */ |
|
224 bool QVersitContactExporterPrivate::documentContainsName(const QVersitDocument &document) |
|
225 { |
|
226 foreach (const QVersitProperty& property, document.properties()) { |
|
227 const QString& name = property.name(); |
|
228 if (name == QLatin1String("FN") || name == QLatin1String("N")) |
|
229 return true; |
|
230 } |
|
231 return false; |
|
232 } |
|
233 |
|
234 /*! |
|
235 * Encode Contact Name Field Information into the Versit Document |
|
236 */ |
|
237 void QVersitContactExporterPrivate::encodeName( |
|
238 const QContactDetail& detail, |
|
239 const QVersitDocument& document, |
|
240 QList<QVersitProperty>* removedProperties, |
|
241 QList<QVersitProperty>* generatedProperties, |
|
242 QSet<QString>* processedFields) |
|
243 { |
|
244 QContactName contactName = static_cast<QContactName>(detail); |
|
245 if (!contactName.lastName().isEmpty() |
|
246 || !contactName.firstName().isEmpty() |
|
247 || !contactName.middleName().isEmpty() |
|
248 || !contactName.prefix().isEmpty() |
|
249 || !contactName.suffix().isEmpty()) { |
|
250 QVersitProperty property; |
|
251 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
252 property.setValue(QStringList() |
|
253 << contactName.lastName() |
|
254 << contactName.firstName() |
|
255 << contactName.middleName() |
|
256 << contactName.prefix() |
|
257 << contactName.suffix()); |
|
258 property.setValueType(QVersitProperty::CompoundType); |
|
259 *generatedProperties << property; |
|
260 } |
|
261 |
|
262 // Generate an FN field if none is already there |
|
263 // Don't override previously exported FN properties (eg. exported by a DisplayLabel detail) |
|
264 QVersitProperty fnProperty = takeProperty(document, QLatin1String("FN"), removedProperties); |
|
265 if (fnProperty.value().isEmpty()) { |
|
266 fnProperty.setName(QLatin1String("FN")); |
|
267 if (!contactName.customLabel().isEmpty()) { |
|
268 fnProperty.setValue(contactName.customLabel()); |
|
269 } else if (!contactName.firstName().isEmpty()) { |
|
270 if (!contactName.lastName().isEmpty()) { |
|
271 fnProperty.setValue(QString::fromAscii("%1 %2").arg(contactName.firstName(), |
|
272 contactName.lastName())); |
|
273 } else { |
|
274 fnProperty.setValue(contactName.firstName()); |
|
275 } |
|
276 } else if (!contactName.lastName().isEmpty()) { |
|
277 fnProperty.setValue(contactName.lastName()); |
|
278 } |
|
279 } |
|
280 |
|
281 *generatedProperties << fnProperty; |
|
282 *processedFields << QContactName::FieldLastName |
|
283 << QContactName::FieldFirstName |
|
284 << QContactName::FieldMiddleName |
|
285 << QContactName::FieldPrefix |
|
286 << QContactName::FieldSuffix |
|
287 << QContactName::FieldCustomLabel; |
|
288 } |
|
289 |
|
290 /*! |
|
291 * Encode Phone Number Field Information into the Versit Document |
|
292 */ |
|
293 void QVersitContactExporterPrivate::encodePhoneNumber( |
|
294 const QContactDetail& detail, |
|
295 QList<QVersitProperty>* generatedProperties, |
|
296 QSet<QString>* processedFields) |
|
297 { |
|
298 QContactPhoneNumber phoneNumber = static_cast<QContactPhoneNumber>(detail); |
|
299 QStringList subTypes = phoneNumber.subTypes(); |
|
300 QVersitProperty property; |
|
301 if (subTypes.contains(QContactPhoneNumber::SubTypeAssistant)) |
|
302 property.setName(QLatin1String("X-ASSISTANT-TEL")); |
|
303 else |
|
304 property.setName(QLatin1String("TEL")); |
|
305 encodeParameters(property, phoneNumber.contexts(), subTypes); |
|
306 property.setValue(phoneNumber.number()); |
|
307 *generatedProperties << property; |
|
308 *processedFields << QContactPhoneNumber::FieldContext |
|
309 << QContactPhoneNumber::FieldSubTypes |
|
310 << QContactPhoneNumber::FieldNumber; |
|
311 } |
|
312 |
|
313 /*! |
|
314 * Encode Email Field Information into the Versit Document |
|
315 */ |
|
316 void QVersitContactExporterPrivate::encodeEmail( |
|
317 const QContactDetail& detail, |
|
318 QList<QVersitProperty>* generatedProperties, |
|
319 QSet<QString>* processedFields) |
|
320 { |
|
321 QContactEmailAddress emailAddress = static_cast<QContactEmailAddress>(detail); |
|
322 QVersitProperty property; |
|
323 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
324 encodeParameters(property, emailAddress.contexts()); |
|
325 property.setValue(emailAddress.emailAddress()); |
|
326 *generatedProperties << property; |
|
327 *processedFields << QContactEmailAddress::FieldContext |
|
328 << QContactEmailAddress::FieldEmailAddress; |
|
329 } |
|
330 |
|
331 /*! |
|
332 * Encode Address Field Information into the Versit Document |
|
333 */ |
|
334 void QVersitContactExporterPrivate::encodeAddress( |
|
335 const QContactDetail& detail, |
|
336 QList<QVersitProperty>* generatedProperties, |
|
337 QSet<QString>* processedFields) |
|
338 { |
|
339 QContactAddress address = static_cast<QContactAddress>(detail); |
|
340 QVersitProperty property; |
|
341 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
342 encodeParameters(property, address.contexts(), address.subTypes()); |
|
343 property.setValue(QStringList() |
|
344 << address.postOfficeBox() |
|
345 << QString() // Leave out the extended address field |
|
346 << address.street() |
|
347 << address.locality() |
|
348 << address.region() |
|
349 << address.postcode() |
|
350 << address.country()); |
|
351 property.setValueType(QVersitProperty::CompoundType); |
|
352 *generatedProperties << property; |
|
353 *processedFields << QContactAddress::FieldContext |
|
354 << QContactAddress::FieldSubTypes |
|
355 << QContactAddress::FieldPostOfficeBox |
|
356 << QContactAddress::FieldStreet |
|
357 << QContactAddress::FieldLocality |
|
358 << QContactAddress::FieldRegion |
|
359 << QContactAddress::FieldPostcode |
|
360 << QContactAddress::FieldCountry; |
|
361 } |
|
362 |
|
363 /*! |
|
364 * Encode URL Field Information into the Versit Document |
|
365 */ |
|
366 void QVersitContactExporterPrivate::encodeUrl( |
|
367 const QContactDetail& detail, |
|
368 QList<QVersitProperty>* generatedProperties, |
|
369 QSet<QString>* processedFields) |
|
370 { |
|
371 QContactUrl contactUrl = static_cast<QContactUrl>(detail); |
|
372 QVersitProperty property; |
|
373 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
374 encodeParameters(property, contactUrl.contexts()); |
|
375 // The vCard specifications do not define any TYPEs for URL property. |
|
376 // No need to try to convert the subtypes to TYPEs. |
|
377 property.setValue(contactUrl.url()); |
|
378 *generatedProperties << property; |
|
379 *processedFields << QContactUrl::FieldContext |
|
380 << QContactUrl::FieldUrl; |
|
381 } |
|
382 |
|
383 /*! |
|
384 * Encode Uid Field Information into the Versit Document |
|
385 */ |
|
386 void QVersitContactExporterPrivate::encodeUid( |
|
387 const QContactDetail& detail, |
|
388 QList<QVersitProperty>* generatedProperties, |
|
389 QSet<QString>* processedFields) |
|
390 { |
|
391 QContactGuid uid = static_cast<QContactGuid>(detail); |
|
392 QVersitProperty property; |
|
393 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
394 property.setValue(uid.guid()); |
|
395 *generatedProperties << property; |
|
396 *processedFields << QContactGuid::FieldGuid; |
|
397 } |
|
398 |
|
399 /*! |
|
400 * Encode REV Field Information into the Versit Document |
|
401 */ |
|
402 void QVersitContactExporterPrivate::encodeRev( |
|
403 const QContactDetail& detail, |
|
404 QList<QVersitProperty>* generatedProperties, |
|
405 QSet<QString>* processedFields) |
|
406 { |
|
407 QContactTimestamp rev = static_cast<QContactTimestamp>(detail); |
|
408 QString value; |
|
409 QVersitProperty property; |
|
410 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
411 |
|
412 if ( rev.lastModified().toString(Qt::ISODate).size() ) { |
|
413 if ( rev.lastModified().timeSpec() == Qt::UTC ) { |
|
414 value = rev.lastModified().toString(Qt::ISODate) + QLatin1Char('Z'); |
|
415 } |
|
416 else { |
|
417 value = rev.lastModified().toString(Qt::ISODate); |
|
418 } |
|
419 property.setValue(value); |
|
420 *generatedProperties << property; |
|
421 *processedFields << QContactTimestamp::FieldModificationTimestamp; |
|
422 } else if ( rev.created().toString(Qt::ISODate).size()) { |
|
423 if ( rev.created().timeSpec() == Qt::UTC ) { |
|
424 value = rev.created().toString(Qt::ISODate) + QLatin1Char('Z'); |
|
425 } |
|
426 else { |
|
427 value = rev.created().toString(Qt::ISODate); |
|
428 } |
|
429 property.setValue(value); |
|
430 *generatedProperties << property; |
|
431 *processedFields << QContactTimestamp::FieldCreationTimestamp; |
|
432 } |
|
433 } |
|
434 |
|
435 /*! |
|
436 * Encode BirthDay Field Information into the Versit Document |
|
437 */ |
|
438 void QVersitContactExporterPrivate::encodeBirthDay( |
|
439 const QContactDetail& detail, |
|
440 QList<QVersitProperty>* generatedProperties, |
|
441 QSet<QString>* processedFields) |
|
442 { |
|
443 QContactBirthday bday = static_cast<QContactBirthday>(detail); |
|
444 QVersitProperty property; |
|
445 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
446 QString value = bday.date().toString(Qt::ISODate); |
|
447 property.setValue(value); |
|
448 *generatedProperties << property; |
|
449 *processedFields << QContactBirthday::FieldBirthday; |
|
450 } |
|
451 |
|
452 /*! |
|
453 * Encode Comment i.e. Note Field Information into the Versit Document |
|
454 */ |
|
455 void QVersitContactExporterPrivate::encodeNote( |
|
456 const QContactDetail& detail, |
|
457 QList<QVersitProperty>* generatedProperties, |
|
458 QSet<QString>* processedFields) |
|
459 { |
|
460 QContactNote contactNote = static_cast<QContactNote>(detail); |
|
461 QVersitProperty property; |
|
462 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
463 property.setValue(contactNote.note()); |
|
464 *generatedProperties << property; |
|
465 *processedFields << QContactNote::FieldNote; |
|
466 } |
|
467 |
|
468 /*! |
|
469 * Encode Geo Prpoperties Field Information into the Versit Document |
|
470 */ |
|
471 void QVersitContactExporterPrivate::encodeGeoLocation( |
|
472 const QContactDetail& detail, |
|
473 QList<QVersitProperty>* generatedProperties, |
|
474 QSet<QString>* processedFields) |
|
475 { |
|
476 QContactGeoLocation geoLocation = static_cast<QContactGeoLocation>(detail); |
|
477 QVersitProperty property; |
|
478 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
479 property.setValue(QStringList() << QString::number(geoLocation.longitude()) |
|
480 << QString::number(geoLocation.latitude())); |
|
481 property.setValueType(QVersitProperty::CompoundType); |
|
482 *generatedProperties << property; |
|
483 *processedFields << QContactGeoLocation::FieldLongitude |
|
484 << QContactGeoLocation::FieldLatitude; |
|
485 } |
|
486 |
|
487 /*! |
|
488 * Encode organization properties to the versit document |
|
489 */ |
|
490 void QVersitContactExporterPrivate::encodeOrganization( |
|
491 const QContactDetail& detail, |
|
492 QList<QVersitProperty>* generatedProperties, |
|
493 QSet<QString>* processedFields) |
|
494 { |
|
495 QContactOrganization organization = static_cast<QContactOrganization>(detail); |
|
496 if (organization.title().length() > 0) { |
|
497 QVersitProperty property; |
|
498 property.setName(QLatin1String("TITLE")); |
|
499 property.setValue(organization.title()); |
|
500 *generatedProperties << property; |
|
501 *processedFields << QContactOrganization::FieldTitle; |
|
502 } |
|
503 if (organization.name().length() > 0 || organization.department().size() > 0) { |
|
504 QVersitProperty property; |
|
505 property.setName(QLatin1String("ORG")); |
|
506 QStringList values(organization.name()); |
|
507 values.append(organization.department()); |
|
508 property.setValue(values); |
|
509 property.setValueType(QVersitProperty::CompoundType); |
|
510 *generatedProperties << property; |
|
511 *processedFields << QContactOrganization::FieldName |
|
512 << QContactOrganization::FieldDepartment; |
|
513 } |
|
514 if (organization.logoUrl().isValid()) { |
|
515 QVersitProperty property; |
|
516 if (encodeContentFromFile(organization.logoUrl().toString(), property)) { |
|
517 property.setName(QLatin1String("LOGO")); |
|
518 *generatedProperties << property; |
|
519 *processedFields << QContactOrganization::FieldLogoUrl; |
|
520 } |
|
521 } |
|
522 if (organization.assistantName().length() > 0) { |
|
523 QVersitProperty property; |
|
524 property.setName(QLatin1String("X-ASSISTANT")); |
|
525 property.setValue(organization.assistantName()); |
|
526 *generatedProperties << property; |
|
527 *processedFields << QContactOrganization::FieldAssistantName; |
|
528 } |
|
529 |
|
530 if (organization.role().length() > 0) { |
|
531 QVersitProperty property; |
|
532 property.setName(QLatin1String("ROLE")); |
|
533 property.setValue(organization.role()); |
|
534 *generatedProperties << property; |
|
535 *processedFields << QContactOrganization::FieldRole; |
|
536 } |
|
537 } |
|
538 |
|
539 void QVersitContactExporterPrivate::encodeRingtone( |
|
540 const QContactDetail &detail, |
|
541 QList<QVersitProperty>* generatedProperties, |
|
542 QSet<QString>* processedFields) |
|
543 { |
|
544 QContactRingtone ringtone = static_cast<QContactRingtone>(detail); |
|
545 QVersitProperty property; |
|
546 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
547 if (encodeContentFromFile(ringtone.audioRingtoneUrl().toLocalFile(), property)) { |
|
548 *generatedProperties << property; |
|
549 *processedFields << QContactRingtone::FieldAudioRingtoneUrl; |
|
550 } |
|
551 } |
|
552 |
|
553 /*! |
|
554 * Encode thumbnail content into the Versit Document |
|
555 */ |
|
556 void QVersitContactExporterPrivate::encodeThumbnail( |
|
557 const QContactDetail &detail, |
|
558 QList<QVersitProperty>* generatedProperties, |
|
559 QSet<QString>* processedFields) |
|
560 { |
|
561 QContactThumbnail contactThumbnail = static_cast<QContactThumbnail>(detail); |
|
562 QVersitProperty property; |
|
563 property.setName(QLatin1String("PHOTO")); |
|
564 QImage image = contactThumbnail.thumbnail(); |
|
565 if (image.isNull()) |
|
566 return; |
|
567 QByteArray imageData; |
|
568 QBuffer buffer(&imageData); |
|
569 buffer.open(QIODevice::WriteOnly); |
|
570 // Always store a pixmap as a PNG. |
|
571 if (!image.save(&buffer, "PNG")) |
|
572 return; |
|
573 property.setValue(imageData); |
|
574 property.insertParameter(QLatin1String("TYPE"), QLatin1String("PNG")); |
|
575 *generatedProperties << property; |
|
576 *processedFields << QContactThumbnail::FieldThumbnail; |
|
577 } |
|
578 |
|
579 /*! |
|
580 * Encode avatar URIs into the Versit Document |
|
581 */ |
|
582 void QVersitContactExporterPrivate::encodeAvatar( |
|
583 const QContactDetail &detail, |
|
584 QList<QVersitProperty>* generatedProperties, |
|
585 QSet<QString>* processedFields) |
|
586 { |
|
587 QVersitProperty property; |
|
588 property.setName(QLatin1String("PHOTO")); |
|
589 QContactAvatar contactAvatar = static_cast<QContactAvatar>(detail); |
|
590 QUrl imageUrl(contactAvatar.imageUrl()); |
|
591 // XXX: fix up this mess: checking the scheme here and in encodeContentFromFile, |
|
592 // organisation logo and ringtone are QStrings but avatar is a QUrl |
|
593 if (!imageUrl.scheme().isEmpty() && !imageUrl.host().isEmpty()) { |
|
594 property.insertParameter(QLatin1String("VALUE"), QLatin1String("URL")); |
|
595 property.setValue(imageUrl.toString()); |
|
596 *generatedProperties << property; |
|
597 *processedFields << QContactAvatar::FieldImageUrl; |
|
598 } else { |
|
599 if (encodeContentFromFile(contactAvatar.imageUrl().toString(), property)) { |
|
600 *generatedProperties << property; |
|
601 *processedFields << QContactAvatar::FieldImageUrl; |
|
602 } |
|
603 } |
|
604 } |
|
605 |
|
606 /*! |
|
607 * Encode gender property information into Versit Document |
|
608 */ |
|
609 void QVersitContactExporterPrivate::encodeGender( |
|
610 const QContactDetail &detail, |
|
611 QList<QVersitProperty>* generatedProperties, |
|
612 QSet<QString>* processedFields) |
|
613 { |
|
614 QContactGender gender = static_cast<QContactGender>(detail); |
|
615 QVersitProperty property; |
|
616 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
617 property.setValue(gender.gender()); |
|
618 *generatedProperties << property; |
|
619 *processedFields << QContactGender::FieldGender; |
|
620 } |
|
621 |
|
622 /*! |
|
623 * Encodes nickname property information into the Versit Document |
|
624 */ |
|
625 void QVersitContactExporterPrivate::encodeNickname( |
|
626 const QContactDetail &detail, |
|
627 const QVersitDocument& document, |
|
628 QList<QVersitProperty>* removedProperties, |
|
629 QList<QVersitProperty>* generatedProperties, |
|
630 QSet<QString>* processedFields) |
|
631 { |
|
632 QContactNickname nicknameDetail = static_cast<QContactNickname>(detail); |
|
633 QVersitProperty property = takeProperty(document, QLatin1String("X-NICKNAME"), removedProperties); |
|
634 property.setName(QLatin1String("X-NICKNAME")); |
|
635 QStringList value(property.variantValue().toStringList()); |
|
636 value.append(nicknameDetail.nickname()); |
|
637 property.setValue(value); |
|
638 property.setValueType(QVersitProperty::ListType); |
|
639 *generatedProperties << property; |
|
640 *processedFields << QContactNickname::FieldNickname; |
|
641 } |
|
642 |
|
643 /*! |
|
644 * Encodes a contact tag into the Versit Document |
|
645 */ |
|
646 void QVersitContactExporterPrivate::encodeTag( |
|
647 const QContactDetail &detail, |
|
648 const QVersitDocument& document, |
|
649 QList<QVersitProperty>* removedProperties, |
|
650 QList<QVersitProperty>* generatedProperties, |
|
651 QSet<QString>* processedFields) |
|
652 { |
|
653 QContactTag tagDetail = static_cast<QContactTag>(detail); |
|
654 QVersitProperty property = takeProperty(document, QLatin1String("CATEGORIES"), removedProperties); |
|
655 property.setName(QLatin1String("CATEGORIES")); |
|
656 QStringList value(property.variantValue().toStringList()); |
|
657 value.append(tagDetail.tag()); |
|
658 property.setValue(value); |
|
659 property.setValueType(QVersitProperty::ListType); |
|
660 *generatedProperties << property; |
|
661 *processedFields << QContactTag::FieldTag; |
|
662 } |
|
663 |
|
664 /*! |
|
665 * Encode anniversary information into Versit Document |
|
666 */ |
|
667 void QVersitContactExporterPrivate::encodeAnniversary( |
|
668 const QContactDetail &detail, |
|
669 QList<QVersitProperty>* generatedProperties, |
|
670 QSet<QString>* processedFields) |
|
671 { |
|
672 QContactAnniversary anniversary = static_cast<QContactAnniversary>(detail); |
|
673 QVersitProperty property; |
|
674 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
675 property.setValue(anniversary.originalDate().toString(Qt::ISODate)); |
|
676 *generatedProperties << property; |
|
677 *processedFields << QContactAnniversary::FieldOriginalDate; |
|
678 } |
|
679 |
|
680 /*! |
|
681 * Encode online account information into the Versit Document |
|
682 */ |
|
683 void QVersitContactExporterPrivate::encodeOnlineAccount( |
|
684 const QContactDetail &detail, |
|
685 QList<QVersitProperty>* generatedProperties, |
|
686 QSet<QString>* processedFields) |
|
687 { |
|
688 QContactOnlineAccount onlineAccount = static_cast<QContactOnlineAccount>(detail); |
|
689 QStringList subTypes = onlineAccount.subTypes(); |
|
690 |
|
691 if (subTypes.contains(QContactOnlineAccount::SubTypeSip) || |
|
692 subTypes.contains(QContactOnlineAccount::SubTypeSipVoip) || |
|
693 subTypes.contains(QContactOnlineAccount::SubTypeVideoShare) || |
|
694 subTypes.contains(QContactOnlineAccount::SubTypeImpp)) { |
|
695 QVersitProperty property; |
|
696 encodeParameters(property, onlineAccount.contexts(), subTypes); |
|
697 QString name(QLatin1String("X-SIP")); |
|
698 if (subTypes.contains(QContactOnlineAccount::SubTypeImpp)) |
|
699 name = QLatin1String("X-IMPP"); |
|
700 property.setName(name); |
|
701 property.setValue(onlineAccount.accountUri()); |
|
702 *generatedProperties << property; |
|
703 *processedFields << QContactOnlineAccount::FieldSubTypes |
|
704 << QContactOnlineAccount::FieldAccountUri; |
|
705 } |
|
706 } |
|
707 |
|
708 /*! |
|
709 * Encode family versit property if its supported in Versit Document |
|
710 */ |
|
711 void QVersitContactExporterPrivate::encodeFamily( |
|
712 const QContactDetail &detail, |
|
713 QList<QVersitProperty>* generatedProperties, |
|
714 QSet<QString>* processedFields) |
|
715 { |
|
716 QContactFamily family = static_cast<QContactFamily>(detail); |
|
717 |
|
718 if (family.spouse().size()) { |
|
719 QVersitProperty property; |
|
720 property.setName(QLatin1String("X-SPOUSE")); |
|
721 property.setValue(family.spouse()); |
|
722 *generatedProperties << property; |
|
723 *processedFields << QContactFamily::FieldSpouse; |
|
724 } |
|
725 |
|
726 if (family.children().size()) { |
|
727 QVersitProperty property; |
|
728 property.setName(QLatin1String("X-CHILDREN")); |
|
729 property.setValue(family.children()); |
|
730 property.setValueType(QVersitProperty::ListType); |
|
731 *generatedProperties << property; |
|
732 *processedFields << QContactFamily::FieldChildren; |
|
733 } |
|
734 } |
|
735 |
|
736 |
|
737 /*! |
|
738 * Encode family versit property if its supported in Versit Document |
|
739 */ |
|
740 void QVersitContactExporterPrivate::encodeDisplayLabel( |
|
741 const QContactDetail &detail, |
|
742 const QVersitDocument& document, |
|
743 QList<QVersitProperty>* removedProperties, |
|
744 QList<QVersitProperty>* generatedProperties, |
|
745 QSet<QString>* processedFields) |
|
746 { |
|
747 // Override any previous FN property |
|
748 QVersitProperty property = takeProperty(document, QLatin1String("FN"), removedProperties); |
|
749 property.setName(mPropertyMappings.value(detail.definitionName())); |
|
750 QContactDisplayLabel displayLabel = static_cast<QContactDisplayLabel>(detail); |
|
751 if (!displayLabel.label().isEmpty()) { |
|
752 property.setValue(displayLabel.label()); |
|
753 *generatedProperties << property; |
|
754 *processedFields << QContactDisplayLabel::FieldLabel; |
|
755 } |
|
756 } |
|
757 |
|
758 /*! |
|
759 * Finds a property in the \a document with the given \a propertyName, removes it and returns it. |
|
760 */ |
|
761 QVersitProperty QVersitContactExporterPrivate::takeProperty(const QVersitDocument& document, |
|
762 const QString& propertyName, |
|
763 QList<QVersitProperty>* toBeRemoved) { |
|
764 foreach (const QVersitProperty& currentProperty, document.properties()) { |
|
765 if (currentProperty.name() == propertyName) { |
|
766 *toBeRemoved << currentProperty; |
|
767 return currentProperty; |
|
768 } |
|
769 } |
|
770 return QVersitProperty(); |
|
771 } |
|
772 |
|
773 /*! |
|
774 * Check if \a resourceIdentifier represents a valid remote resource |
|
775 */ |
|
776 bool QVersitContactExporterPrivate::isValidRemoteUrl( |
|
777 const QString& resourceIdentifier) |
|
778 { |
|
779 QUrl remoteResource(resourceIdentifier); |
|
780 if ((!remoteResource.scheme().isEmpty() && |
|
781 !remoteResource.host().isEmpty()) || |
|
782 resourceIdentifier.contains(QLatin1String("www."), Qt::CaseInsensitive)) |
|
783 return true; |
|
784 return false; |
|
785 } |
|
786 |
|
787 /*! |
|
788 * Encode parameters to \a property |
|
789 */ |
|
790 void QVersitContactExporterPrivate::encodeParameters( |
|
791 QVersitProperty& property, |
|
792 const QStringList& contexts, |
|
793 const QStringList& subTypes) |
|
794 { |
|
795 QStringList parameterList(contexts); // Contexts should be encoded first |
|
796 parameterList << subTypes; |
|
797 while (!parameterList.isEmpty()) { |
|
798 QString value = parameterList.takeLast(); |
|
799 QString mappedValue = mParameterMappings.value(value); |
|
800 if (mappedValue.length() > 0) { |
|
801 // QVersitProperty::addParameter inserts into beginning. |
|
802 // This is why the last value is taken from the list |
|
803 property.insertParameter(QLatin1String("TYPE"),mappedValue); |
|
804 } |
|
805 } |
|
806 } |
|
807 |
|
808 /*! |
|
809 * Encode embedded content from the given \a resourcePath into \a property. |
|
810 */ |
|
811 bool QVersitContactExporterPrivate::encodeContentFromFile(const QString& resourcePath, |
|
812 QVersitProperty& property) |
|
813 { |
|
814 bool encodeContent = false; |
|
815 QVariant value; |
|
816 QByteArray imageData; |
|
817 QString mimeType; |
|
818 if (isValidRemoteUrl( resourcePath )) { |
|
819 encodeContent = true; |
|
820 value.setValue(resourcePath); |
|
821 property.insertParameter(QLatin1String("VALUE"), QLatin1String("URL")); |
|
822 } else if (mResourceHandler |
|
823 && mResourceHandler->loadResource(resourcePath, &imageData, &mimeType)) { |
|
824 value.setValue(imageData); |
|
825 if (!mimeType.isEmpty()) { |
|
826 // If mimeType is (eg.) "image/jpeg", set type parameter to "JPEG" |
|
827 int slashIndex = mimeType.indexOf(QLatin1Char('/')); |
|
828 if (slashIndex >= 0) |
|
829 property.insertParameter(QLatin1String("TYPE"), |
|
830 mimeType.remove(0, slashIndex+1).toUpper()); |
|
831 } |
|
832 encodeContent = true; |
|
833 } else { |
|
834 // The file doesn't exist. Don't encode the path to a local file. |
|
835 } |
|
836 property.setValue(value); |
|
837 return encodeContent; |
|
838 } |