1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtVersit module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
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 The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
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 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34#include "qversitcontactexporter.h"
35#include "qversitcontactexporter_p.h"
36
37QT_BEGIN_NAMESPACE_VERSIT
38
39/*!
40 \deprecated
41 \class QVersitContactExporterDetailHandler
42 \brief The QVersitContactExporterDetailHandler class is the legacy interface for clients wishing
43 to implement custom export behaviour for certain contact details.
44
45 This interface is replaced by QVersitContactExporterDetailHandlerV2. For general information on
46 extending Qt Versit, see the document on \l{Qt Versit Plugins}.
47
48
49 \sa QVersitContactExporter
50 */
51
52/*!
53 \fn QVersitContactExporterDetailHandler::~QVersitContactExporterDetailHandler()
54 Frees any memory in use by this handler.
55 */
56
57/*!
58 \fn bool QVersitContactExporterDetailHandler::preProcessDetail(const QContact& contact, const QContactDetail& detail, QVersitDocument* document)
59 Process \a detail and update \a document with the corresponding QVersitProperty(s).
60 \a contact provides the context within which the detail was found.
61
62 Returns true if the detail has been handled and requires no further processing, false otherwise.
63
64 This function is called on every QContactDetail encountered during an export. Supply this
65 function and return true to implement custom export behaviour.
66 */
67
68/*!
69 \fn bool QVersitContactExporterDetailHandler::postProcessDetail(const QContact& contact, const QContactDetail& detail, bool alreadyProcessed, QVersitDocument* document)
70 Process \a detail and update \a document with the corresponding QVersitProperty(s).
71 \a contact provides the context within which the detail was found.
72 \a alreadyProcessed is true if the detail has already been processed either by
73 \l preProcessDetail() or by QVersitContactExporter itself.
74
75 Returns true if the detail has been handled, false otherwise.
76
77 This function is called on every \l QContactDetail encountered during an export. This can be
78 used to implement support for QContactDetails not supported by QVersitContactExporter.
79 */
80
81/*!
82 \class QVersitContactExporterDetailHandlerV2
83 \brief The QVersitContactExporterDetailHandlerV2 class is an interface for specifying custom
84 export behaviour for certain contact details.
85 \ingroup versit-extension
86 \inmodule QtVersit
87
88 This interface supercedes QVersitContactExporterDetailHandler. For general information on
89 extending Qt Versit, see the document on \l{Qt Versit Plugins}.
90
91
92 \sa QVersitContactExporter
93 */
94
95/*!
96 \fn QVersitContactExporterDetailHandlerV2::~QVersitContactExporterDetailHandlerV2()
97 Frees any memory in use by this handler.
98 */
99
100/*!
101 \fn void QVersitContactExporterDetailHandlerV2::detailProcessed(const QContact& contact, const QContactDetail& detail, const QVersitDocument& document, QSet<int>* processedFields, QList<QVersitProperty>* toBeRemoved, QList<QVersitProperty>* toBeAdded)
102
103 Process \a detail and provide a list of updated \l{QVersitProperty}{QVersitProperties} by
104 modifying the \a toBeRemoved and \a toBeAdded lists.
105
106 This function is called on every QContactDetail encountered during an export, after the detail has
107 been processed by the QVersitContactExporter. An implementation of this function can be made to
108 provide support for QContactDetails not supported by QVersitContactExporter.
109
110 The supplied \a contact is the container for the \a detail. \a processedFields contains a list of
111 fields in the \a detail that were considered by the QVersitContactExporter or another handler in
112 processing the detail. \a document holds the state of the document before the detail was
113 processed by the exporter.
114
115 \a toBeRemoved and \a toBeAdded are initially filled with a list of properties that the exporter
116 will remove from and add to the document. These lists can be modified (by removing, modifying or
117 adding properties) by the handler to control the changes that will actually be made to the
118 document. If a property is to be modified in the document, the old version will appear in the
119 \a toBeRemoved list and the new version will appear in the \a toBeAdded list. When the handler
120 uses a field from the detail, it should update the processedFields set to reflect this to inform
121 later handlers that the field has already been processed.
122
123 After the handler returns control back to the exporter, the properties in the \a toBeRemoved
124 list will be removed and the properties in the \a toBeAdded list will be appended to the document.
125 */
126
127/*!
128 \fn void QVersitContactExporterDetailHandlerV2::contactProcessed(const QContact& contact, QVersitDocument* document)
129 Perform any final processing on the \a document generated by the \a contact. This can be
130 implemented by the handler to clear any internal state before moving onto the next contact.
131
132 This function is called after all QContactDetails have been handled by the
133 QVersitContactExporter.
134*/
135
136/*!
137 \class QVersitContactExporter
138 \brief The QVersitContactExporter class converts \l {QContact}{QContacts} into
139 \l {QVersitDocument}{QVersitDocuments}.
140 \ingroup versit
141 \inmodule QtVersit
142
143 This class is used to convert lists of \l {QContact}{QContacts} (which may be stored in a
144 QContactManager) into lists of \l {QVersitDocument}{QVersitDocuments} (which may be written to
145 an I/O device using QVersitReader. Unless there is an error, there is a one-to-one mapping
146 between contacts and Versit documents. The exporter can be extended by clients by associating
147 resource and detail handlers.
148
149 Here is a simple example of how to use QVersitContactExporter:
150 \snippet qtversitdocsample/qtversitdocsample.cpp Export example
151
152 \section1 Extension via handlers
153
154 A \l QVersitResourceHandler is associated with the exporter to supply the behaviour for loading
155 files from persistent storage. By default, this is set to a \l QVersitDefaultResourceHandler,
156 which supports basic resource loading from the file system. An alternative resource handler
157 can be specified with setResourceHandler().
158
159 By associating a \l QVersitContactExporterDetailHandlerV2 with the exporter using
160 setDetailHandler(), the client can pass in a handler to override the processing of details and/or
161 handle details that QVersitContactExporter doesn't support. Also, handlers can be implicitly
162 associated to an exporter through the \l{Qt Versit Plugins}{handler plugin mechanism}. The exporter
163 can be constructed with a profile, which gives hints about what kind of handlers should be added
164 to it. For example, the backup profile can be used to instruct the exporter to encode any unknown
165 details in the vCard such that it can be reconstructed later (a QVersitContactImporter constructed
166 under the backup profile can be used to decode it). To illustrate, a backup exporter can be
167 constructed with:
168 \code
169 QVersitContactExporter exporter(QVersitContactHandlerFactory::ProfileBackup);
170 \endcode
171 For more details on how the backup plugin works, see \l{Qt Versit Plugins}
172
173 \section1 Exporting group relationships
174 The exporter does not handle QContactRelationships at all.
175
176 Some managers use the \l{QContactRelationship::HasMember()}{HasMember} QContactRelationship along
177 with contacts of type \l{QContactType::TypeGroup}{TypeGroup} to indicate categorization of
178 contacts. In vCard, categorization is represented by the CATEGORIES property, which has
179 semantics most similar to the QContactTag detail. For contact manager backends that supports
180 groups but not QContactTag, if the categorization information needs to be retained through
181 CATEGORIES vCard properties, extra work can be done to convert from group relationships to
182 QContactTag before passing the contact list to the exporter. Below is some example code that
183 does this translation.
184
185 \snippet qtversitdocsample/qtversitdocsample.cpp Export relationship example
186
187 \section1 Other implementation notes
188
189 Some Android devices do not properly handle the \c FN vCard property. If a
190 DisplayLabel is set on a contact and this class is used to generate a vCard, the receiving device
191 might display this label in an unexpected field (eg. Last Name).
192 The vCard specification requires the \c FN property to be present. However, because of this
193 interoperability issue, Qt Versit only generates an FN property if a Displaylabel is set.
194
195 \sa QVersitDocument, QVersitProperty, QVersitResourceHandler, QVersitContactExporterDetailHandlerV2
196 */
197
198/*!
199 \enum QVersitContactExporter::Error
200 This enum specifies an error that occurred during the most recent call to exportContacts()
201 \value NoError The most recent operation was successful
202 \value EmptyContactError One of the contacts was empty
203 \value NoNameError One of the contacts has no QContactName field
204 */
205
206
207/*!
208 * Constructs a new contact exporter
209 */
210QVersitContactExporter::QVersitContactExporter()
211 : d(new QVersitContactExporterPrivate())
212{
213}
214
215/*!
216 * Constructs a new exporter for the given \a profile. The profile strings should be one of those
217 * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Qt Versit
218 * Plugins}{Versit plugin}.
219 *
220 * The profile determines which plugins will be loaded to supplement the exporter.
221 */
222QVersitContactExporter::QVersitContactExporter(const QString& profile)
223{
224 if (profile.isEmpty())
225 d = new QVersitContactExporterPrivate(QStringList());
226 else
227 d = new QVersitContactExporterPrivate(QStringList() << profile);
228}
229
230/*!
231 * Constructs a new exporter for the given \a profiles. The profile strings should be one of those
232 * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Qt Versit
233 * Plugins}{Versit plugin}.
234 *
235 * The profiles determine which plugins will be loaded to supplement the exporter.
236 */
237QVersitContactExporter::QVersitContactExporter(const QStringList& profiles)
238 : d(new QVersitContactExporterPrivate(profiles))
239{
240}
241
242/*!
243 * Frees any memory in use by this contact exporter.
244 */
245QVersitContactExporter::~QVersitContactExporter()
246{
247 delete d;
248}
249
250/*!
251 * Converts \a contacts into a list of corresponding QVersitDocuments, using the format given by
252 * \a versitType.
253 *
254 * Returns true on success. If any of the contacts could not be exported, false is returned and
255 * errorMap() will return a list describing the errors that occurred. The successfully exported
256 * documents will still be available via documents().
257 *
258 * \sa documents(), errorMap()
259 */
260bool QVersitContactExporter::exportContacts(
261 const QList<QTCONTACTS_PREPEND_NAMESPACE(QContact)>& contacts,
262 QVersitDocument::VersitType versitType)
263{
264 int contactIndex = 0;
265 d->mDocuments.clear();
266 d->mErrors.clear();
267 bool ok = true;
268 foreach (const QTCONTACTS_PREPEND_NAMESPACE(QContact)& contact, contacts) {
269 if (contact.isEmpty()) {
270 d->mErrors[contactIndex] = EmptyContactError;
271 ok = false;
272 continue;
273 }
274
275 QVersitDocument versitDocument;
276 versitDocument.setType(versitType);
277 versitDocument.setComponentType(QStringLiteral("VCARD"));
278 d->exportContact(contact, versitDocument);
279 d->mDocuments.append(t: versitDocument);
280 contactIndex++;
281 }
282
283 return ok;
284}
285
286/*!
287 * Returns the documents exported in the most recent call to exportContacts().
288 *
289 * \sa exportContacts()
290 */
291QList<QVersitDocument> QVersitContactExporter::documents() const
292{
293 return d->mDocuments;
294}
295
296/*!
297 * \obsolete
298 *
299 * Use \l errorMap() instead.
300 */
301QMap<int, QVersitContactExporter::Error> QVersitContactExporter::errors() const
302{
303 return d->mErrors;
304}
305
306/*!
307 * Returns the map of errors encountered in the most recent call to exportContacts(). The key is
308 * the index into the input list of contacts and the value is the error that occurred on that
309 * contact.
310 *
311 * \sa exportContacts()
312 */
313QMap<int, QVersitContactExporter::Error> QVersitContactExporter::errorMap() const
314{
315 return d->mErrors;
316}
317
318/*!
319 * \deprecated
320 * Sets \a handler to be the handler for processing QContactDetails, or 0 to have no handler.
321 *
322 * Does not take ownership of the handler. The client should ensure the handler remains valid for
323 * the lifetime of the exporter. This function is used for version 1 handlers.
324 *
325 * Only one detail handler can be set. If another detail handler (of any version) was
326 * previously set, it will no longer be associated with the exporter.
327 */
328void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandler* handler)
329{
330 d->mDetailHandlerVersion = 1;
331 d->mDetailHandler = handler;
332 d->mDetailHandler2 = 0;
333}
334
335/*!
336 * Sets \a handler to be the handler for processing QContactDetails, or 0 to have no handler.
337 *
338 * Does not take ownership of the handler. The client should ensure the handler remains valid for
339 * the lifetime of the exporter. This function is used for version 2 and higher handlers.
340 *
341 * Only one detail handler can be set. If another detail handler (of any version) was
342 * previously set, it will no longer be associated with the exporter.
343 */
344void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandlerV2* handler)
345{
346 d->mDetailHandlerVersion = 2;
347 d->mDetailHandler = 0;
348 d->mDetailHandler2 = handler;
349}
350
351/*!
352 * \deprecated
353 * Gets the handler for processing QContactDetails.
354 */
355QVersitContactExporterDetailHandler* QVersitContactExporter::detailHandler() const
356{
357 return d->mDetailHandler;
358}
359
360/*!
361 * Sets \a handler to be the handler to load files with, or 0 to have no handler.
362 *
363 * Does not take ownership of the handler. The client should ensure the handler remains valid for
364 * the lifetime of the exporter.
365 */
366void QVersitContactExporter::setResourceHandler(QVersitResourceHandler* handler)
367{
368 d->mResourceHandler = handler;
369}
370
371/*!
372 * Returns the associated resource handler.
373 */
374QVersitResourceHandler* QVersitContactExporter::resourceHandler() const
375{
376 return d->mResourceHandler;
377}
378
379QT_END_NAMESPACE_VERSIT
380

source code of qtpim/src/versit/qversitcontactexporter.cpp