|
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 |
|
43 #include "qversitcontactexporter.h" |
|
44 #include "qversitcontactexporter_p.h" |
|
45 #include "qvcardbackuphandlers_p.h" |
|
46 #include "qmobilityglobal.h" |
|
47 |
|
48 #include <qcontact.h> |
|
49 #include <qcontactdetail.h> |
|
50 |
|
51 QTM_USE_NAMESPACE |
|
52 |
|
53 /*! |
|
54 \deprecated |
|
55 \class QVersitContactExporterDetailHandler |
|
56 \brief The QVersitContactExporterDetailHandler class is an interface for clients wishing to |
|
57 implement custom export behaviour for certain contact details. |
|
58 |
|
59 This interface is replaced by QVersitContactExporterDetailHandlerV2. |
|
60 \ingroup versit |
|
61 |
|
62 \sa QVersitContactExporter |
|
63 */ |
|
64 |
|
65 /*! |
|
66 \fn QVersitContactExporterDetailHandler::~QVersitContactExporterDetailHandler() |
|
67 Frees any memory in use by this handler. |
|
68 */ |
|
69 |
|
70 /*! |
|
71 \fn bool QVersitContactExporterDetailHandler::preProcessDetail(const QContact& contact, const QContactDetail& detail, QVersitDocument* document) |
|
72 Process \a detail and update \a document with the corresponding QVersitProperty(s). |
|
73 \a contact provides the context within which the detail was found. |
|
74 |
|
75 Returns true if the detail has been handled and requires no further processing, false otherwise. |
|
76 |
|
77 This function is called on every QContactDetail encountered during an export. Supply this |
|
78 function and return true to implement custom export behaviour. |
|
79 */ |
|
80 |
|
81 /*! |
|
82 \fn bool QVersitContactExporterDetailHandler::postProcessDetail(const QContact& contact, const QContactDetail& detail, bool alreadyProcessed, QVersitDocument* document) |
|
83 Process \a detail and update \a document with the corresponding QVersitProperty(s). |
|
84 \a contact provides the context within which the detail was found. |
|
85 \a alreadyProcessed is true if the detail has already been processed either by |
|
86 \l preProcessDetail() or by QVersitContactExporter itself. |
|
87 |
|
88 Returns true if the detail has been handled, false otherwise. |
|
89 |
|
90 This function is called on every \l QContactDetail encountered during an export. This can be |
|
91 used to implement support for QContactDetails not supported by QVersitContactExporter. |
|
92 */ |
|
93 |
|
94 /*! |
|
95 \class QVersitContactExporterDetailHandlerV2 |
|
96 \brief The QVersitContactExporterDetailHandlerV2 class is an interface for clients wishing to |
|
97 implement custom export behaviour for certain contact details. |
|
98 |
|
99 This interface supercedes QVersitContactImporterPropertyHandler. |
|
100 |
|
101 \ingroup versit |
|
102 |
|
103 \sa QVersitContactExporter |
|
104 */ |
|
105 |
|
106 /*! |
|
107 \fn QVersitContactExporterDetailHandlerV2::~QVersitContactExporterDetailHandlerV2() |
|
108 Frees any memory in use by this handler. |
|
109 */ |
|
110 |
|
111 /*! |
|
112 \fn void QVersitContactExporterDetailHandlerV2::detailProcessed(const QContact& contact, const QContactDetail& detail, const QSet<QString>& processedFields, const QVersitDocument& document, QList<QVersitProperty>* toBeRemoved, QList<QVersitProperty>* toBeAdded) |
|
113 |
|
114 Process \a detail and provide a list of updated \l{QVersitProperty}{QVersitProperties} by |
|
115 modifying the \a toBeRemoved and \a toBeAdded lists. |
|
116 |
|
117 This function is called on every QContactDetail encountered during an export, after the detail has |
|
118 been processed by the QVersitContactExporter. An implementation of this function can be made to |
|
119 provide support for QContactDetails not supported by QVersitContactExporter. |
|
120 |
|
121 The supplied \a contact is the container for the \a detail. \a processedFields contains a list of |
|
122 fields in the \a detail that were considered by the QVersitContactExporter in processing the |
|
123 detail. \a document holds the state of the document before the detail was processed by the |
|
124 exporter. |
|
125 |
|
126 \a toBeRemoved and \a toBeAdded are initially filled with a list of properties that the exporter |
|
127 will remove from and add to the document. These lists can be modified (by removing, modifying or |
|
128 adding properties) by the handler to control the changes that will actually be made to the |
|
129 document. If a property is to be modified in the document, the old version will appear in the |
|
130 \a toBeRemoved list and the new version will appear in the \a toBeAdded list. |
|
131 |
|
132 After the handler returns control back to the exporter, the properties in the \a toBeRemoved |
|
133 list will be removed and the properties in the \a toBeAdded list will be appended to the document. |
|
134 */ |
|
135 |
|
136 /*! |
|
137 \fn void QVersitContactExporterDetailHandlerV2::contactProcessed(const QContact& contact, QVersitDocument* document) |
|
138 Perform any final processing on the \a document generated by the \a contact. This can be |
|
139 implemented by the handler to clear any internal state before moving onto the next contact. |
|
140 |
|
141 This function is called after all QContactDetails have been handled by the |
|
142 QVersitContactExporter. |
|
143 */ |
|
144 |
|
145 /*! |
|
146 \fn int QVersitContactExporterDetailHandlerV2::version() const |
|
147 Returns the version of the handler. Currently, always returns 2. |
|
148 */ |
|
149 |
|
150 /*! |
|
151 \class QVersitContactExporter |
|
152 \brief The QVersitContactExporter class converts \l {QContact}{QContacts} into |
|
153 \l {QVersitDocument}{QVersitDocuments}. |
|
154 \ingroup versit |
|
155 |
|
156 This class is used to convert lists of \l {QContact}{QContacts} (which may be stored in a |
|
157 QContactManager) into lists of \l {QVersitDocument}{QVersitDocuments} (which may be written to |
|
158 an I/O device using QVersitReader. Unless there is an error, there is a one-to-one mapping |
|
159 between contacts and Versit documents. The exporter can be extended by clients by associating |
|
160 resource and detail handlers. |
|
161 |
|
162 A \l QVersitResourceHandler is associated with the exporter to supply the behaviour for loading |
|
163 files from persistent storage. By default, this is set to a \l QVersitDefaultResourceHandler, |
|
164 which supports basic resource loading from the file system. An alternative resource handler |
|
165 can be specified with setResourceHandler(). |
|
166 |
|
167 By associating a \l QVersitContactExporterDetailHandlerV2 with the exporter using |
|
168 setDetailHandler(), the client can pass in a handler to override the processing of details and/or |
|
169 handle details that QVersitContactExporter doesn't support. A "backup" handler is provided by |
|
170 QVersitContactExporterDetailHandlerV2::createBackupHandler(), which serializes any details |
|
171 that the standard QVersitContactExporter doesn't support to the vCard. |
|
172 |
|
173 |
|
174 An example usage of QVersitContactExporter: |
|
175 \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export example |
|
176 |
|
177 \section1 Exporting group relationships |
|
178 The exporter does not handle QContactRelationships at all. |
|
179 |
|
180 Some managers use the \l{QContactRelationship::HasMember}{HasMember} QContactRelationship along |
|
181 with contacts of type \l{QContactType::TypeGroup}{TypeGroup} to indicate categorization of |
|
182 contacts. In vCard, categorization is represented by the CATEGORIES property, which has |
|
183 semantics most similar to the QContactTag detail. For contact manager backends that supports |
|
184 groups but not QContactTag, if the categorization information needs to be retained through |
|
185 CATEGORIES vCard properties, extra work can be done to convert from group relationships to |
|
186 QContactTag before passing the contact list to the exporter. Below is some example code that |
|
187 does this translation. |
|
188 |
|
189 \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export relationship example |
|
190 |
|
191 \sa QVersitDocument, QVersitProperty, QVersitResourceHandler, QVersitContactExporterDetailHandlerV2 |
|
192 */ |
|
193 |
|
194 /*! |
|
195 \enum QVersitContactExporter::Error |
|
196 This enum specifies an error that occurred during the most recent call to exportContacts() |
|
197 \value NoError The most recent operation was successful |
|
198 \value EmptyContactError One of the contacts was empty |
|
199 \value NoNameError One of the contacts has no QContactName field |
|
200 */ |
|
201 |
|
202 |
|
203 /*! |
|
204 Constructs and returns a detail handler that encodes all details not handled by the base exporter. |
|
205 The caller is responsible for deleting the object. |
|
206 |
|
207 This handler encodes all writable details that the exporter doesn't recognise. The format it uses |
|
208 to encode the detail is as follows: |
|
209 \list |
|
210 \o All generated properties will have the name X-NOKIA-QCONTACTFIELD |
|
211 \o All generated properties will have a single Versit group, and all properties generated from a |
|
212 single detail will have the same group. |
|
213 \o All generated properties will have at least the parameters DETAIL, which holds the definition |
|
214 name of the QContactDetail from which it was generated, and FIELD, which holds the name of the |
|
215 field within the detail from which it was generated. |
|
216 \o If the field is of type QString or QByteArray, the property's value is set directly to the |
|
217 value of the field. (For a QByteArray value, the QVersitWriter will base-64 encode it.) |
|
218 \o If the field is of type bool, int, uint, QDate, QTime, QDateTime or QUrl a the property's |
|
219 value is set to a string representation of the field. A parameter DATATYPE is added to the |
|
220 property with value BOOL, INT, UINT, DATE, TIME or DATETIME depending on the type. |
|
221 \o If the field is of some other type, the field value is encoded to a QByteArray via QDataStream |
|
222 (and the resulting byte array is base-64 encoded by the QVersitWriter). In this case, the |
|
223 parameter DATATYPE=VARIANT is added to the Versit property. |
|
224 \endlist |
|
225 |
|
226 For example, a detail with definition name "Pet" and fields "Name"="Rex" and |
|
227 "Age"=(int)14 will be exported to the vCard properties: |
|
228 \code |
|
229 G0.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Name:Rex |
|
230 G0.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Age;DATATYPE=INT:14 |
|
231 \endcode |
|
232 |
|
233 And the next detail (say, "Pet" with a field "Name"="Molly" will generate: |
|
234 \code |
|
235 G1.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Name:Molly |
|
236 \endcode |
|
237 |
|
238 The properties produced by this class can be imported by the importer "backup" property handler |
|
239 (created by QVersitContactImporterPropertyHandlerV2::createBackupHandler()) to reproduce the |
|
240 original \l{QContactDetail}{QContactDetails}. |
|
241 |
|
242 Clients wishing to implement their own detail handler and also benefit from the functionality of |
|
243 the backup handler can use this function to construct one, and wrap a custom |
|
244 QVersitContactExporterDetailHandlerV2 around it. In the implementation of detailProcessed and |
|
245 contactProcessed, the respective functions in the backup handler should be called as the last |
|
246 step (ensuring the arguments are correctly updated and passed through). |
|
247 */ |
|
248 QVersitContactExporterDetailHandlerV2* QVersitContactExporterDetailHandlerV2::createBackupHandler() { |
|
249 return new QVCardExporterBackupHandler; |
|
250 } |
|
251 |
|
252 /*! |
|
253 * Constructs a new contact exporter |
|
254 */ |
|
255 QVersitContactExporter::QVersitContactExporter() |
|
256 : d(new QVersitContactExporterPrivate()) |
|
257 { |
|
258 } |
|
259 |
|
260 /*! |
|
261 * Frees any memory in use by this contact exporter. |
|
262 */ |
|
263 QVersitContactExporter::~QVersitContactExporter() |
|
264 { |
|
265 delete d; |
|
266 } |
|
267 |
|
268 /*! |
|
269 * Converts \a contacts into a list of corresponding QVersitDocuments, using the format given by |
|
270 * \a versitType. |
|
271 * Returns true on success. If any of the contacts could not be exported, false is returned and |
|
272 * errors() will return a list describing the errors that occurred. The successfully exported |
|
273 * documents will still be available via documents(). |
|
274 */ |
|
275 bool QVersitContactExporter::exportContacts( |
|
276 const QList<QContact>& contacts, |
|
277 QVersitDocument::VersitType versitType) |
|
278 { |
|
279 int contactIndex = 0; |
|
280 d->mDocuments.clear(); |
|
281 d->mErrors.clear(); |
|
282 bool ok = true; |
|
283 foreach (const QContact& contact, contacts) { |
|
284 QVersitDocument versitDocument; |
|
285 versitDocument.setType(versitType); |
|
286 QVersitContactExporter::Error error; |
|
287 if (d->exportContact(contact, versitDocument, &error)) { |
|
288 d->mDocuments.append(versitDocument); |
|
289 } else { |
|
290 d->mErrors.insert(contactIndex, error); |
|
291 ok = false; |
|
292 } |
|
293 contactIndex++; |
|
294 } |
|
295 |
|
296 return ok; |
|
297 } |
|
298 |
|
299 /*! |
|
300 * Returns the documents exported in the most recent call to exportContacts(). |
|
301 * |
|
302 * \sa exportContacts() |
|
303 */ |
|
304 QList<QVersitDocument> QVersitContactExporter::documents() const |
|
305 { |
|
306 return d->mDocuments; |
|
307 } |
|
308 |
|
309 /*! |
|
310 * Returns the map of errors encountered in the most recent call to exportContacts(). The key is |
|
311 * the index into the input list of contacts and the value is the error that occurred on that |
|
312 * contact. |
|
313 * |
|
314 * \sa exportContacts() |
|
315 */ |
|
316 QMap<int, QVersitContactExporter::Error> QVersitContactExporter::errors() const |
|
317 { |
|
318 return d->mErrors; |
|
319 } |
|
320 |
|
321 /*! |
|
322 * \deprecated |
|
323 * Sets \a handler to be the handler for processing QContactDetails, or 0 to have no handler. |
|
324 * |
|
325 * Does not take ownership of the handler. The client should ensure the handler remains valid for |
|
326 * the lifetime of the exporter. This function is used for version 1 handlers. |
|
327 * |
|
328 * Only one detail handler can be set. If another detail handler (of any version) was |
|
329 * previously set, it will no longer be associated with the exporter. |
|
330 */ |
|
331 void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandler* handler) |
|
332 { |
|
333 d->mDetailHandlerVersion = 1; |
|
334 d->mDetailHandler = handler; |
|
335 d->mDetailHandler2 = 0; |
|
336 } |
|
337 |
|
338 /*! |
|
339 * Sets \a handler to be the handler for processing QContactDetails, or 0 to have no handler. |
|
340 * |
|
341 * Does not take ownership of the handler. The client should ensure the handler remains valid for |
|
342 * the lifetime of the exporter. This function is used for version 2 and higher handlers. |
|
343 * |
|
344 * Only one detail handler can be set. If another detail handler (of any version) was |
|
345 * previously set, it will no longer be associated with the exporter. |
|
346 */ |
|
347 void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandlerV2* handler) |
|
348 { |
|
349 if (handler) |
|
350 d->mDetailHandlerVersion = handler->version(); |
|
351 d->mDetailHandler = 0; |
|
352 d->mDetailHandler2 = handler; |
|
353 } |
|
354 |
|
355 /*! |
|
356 * \deprecated |
|
357 * Gets the handler for processing QContactDetails. |
|
358 */ |
|
359 QVersitContactExporterDetailHandler* QVersitContactExporter::detailHandler() const |
|
360 { |
|
361 return d->mDetailHandler; |
|
362 } |
|
363 |
|
364 /*! |
|
365 * Sets \a handler to be the handler to load files with, or 0 to have no handler. |
|
366 * |
|
367 * Does not take ownership of the handler. The client should ensure the handler remains valid for |
|
368 * the lifetime of the exporter. |
|
369 */ |
|
370 void QVersitContactExporter::setResourceHandler(QVersitResourceHandler* handler) |
|
371 { |
|
372 d->mResourceHandler = handler; |
|
373 } |
|
374 |
|
375 /*! |
|
376 * Returns the associated resource handler. |
|
377 */ |
|
378 QVersitResourceHandler* QVersitContactExporter::resourceHandler() const |
|
379 { |
|
380 return d->mResourceHandler; |
|
381 } |