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 "qversitcontactimporter.h"
35#include "qversitcontactimporter_p.h"
36
37QT_BEGIN_NAMESPACE_VERSIT
38
39/*!
40 \deprecated
41 \class QVersitContactImporterPropertyHandler
42 \brief The QVersitContactImporterPropertyHandler class is the legacy interface for specifying
43 custom import behaviour for vCard properties.
44
45 This interface is replaced by QVersitContactImporterPropertyHandlerV2. For general information on
46 extending Qt Versit, see the document on \l{Qt Versit Plugins}.
47
48 \sa QVersitContactImporter
49 */
50
51/*!
52 \fn QVersitContactImporterPropertyHandler::~QVersitContactImporterPropertyHandler()
53 Frees any memory in use by this handler.
54 */
55
56/*!
57 \fn bool QVersitContactImporterPropertyHandler::preProcessProperty(const QVersitDocument& document, const QVersitProperty& property, int contactIndex, QContact* contact)
58 Process \a property and update \a contact with the corresponding QContactDetail(s).
59 \a document provides the context within which the property was found.
60 \a contactIndex specifies the position that \a contact will take in the list returned by
61 \l QVersitContactImporter::importDocuments().
62
63 Returns true if the property has been handled and requires no further processing, false
64 otherwise.
65
66 This function is called on every QVersitProperty encountered during an import. Supply this
67 function and return true to implement custom import behaviour.
68 */
69
70/*!
71 \fn bool QVersitContactImporterPropertyHandler::postProcessProperty(const QVersitDocument& document, const QVersitProperty& property, bool alreadyProcessed, int contactIndex, QContact* contact)
72 Process \a property and update \a contact with the corresponding QContactDetail(s).
73 \a document provides the context within which the property was found.
74 \a contactIndex specifies the position that \a contact will take in the list returned by
75 \l QVersitContactImporter::importDocuments().
76 \a alreadyProcessed is true if the detail has already been processed either by
77 \l preProcessProperty() or by QVersitContactImporter itself.
78
79 Returns true if the property has been handled, false otherwise.
80
81 This function is called on every QVersitProperty encountered during an import. This can be
82 used to implement support for vCard properties not supported by QVersitContactImporter.
83 */
84
85/*!
86 \class QVersitContactImporterPropertyHandlerV2
87 \brief The QVersitContactImporterPropertyHandlerV2 class is an interface for specifying
88 custom import behaviour for vCard properties.
89 \ingroup versit-extension
90 \inmodule QtVersit
91
92 This interface supercedes QVersitContactImporterPropertyHandler. For general information on
93 extending Qt Versit, see the document on \l{Qt Versit Plugins}.
94
95 \sa QVersitContactImporter
96 */
97
98/*!
99 \fn QVersitContactImporterPropertyHandlerV2::~QVersitContactImporterPropertyHandlerV2()
100 Frees any memory in use by this handler.
101 */
102
103/*!
104 \fn void QVersitContactImporterPropertyHandlerV2::propertyProcessed(const QVersitDocument& document, const QVersitProperty& property, const QContact& contact, bool* alreadyProcessed, QList<QContactDetail>* updatedDetails)
105 Process \a property and provide a list of updated details by adding them to \a updatedDetails.
106
107 This function is called on every QVersitProperty encountered during an import, after the property
108 has been processed by the QVersitContactImporter. An implementation of this function can be made
109 to provide support for vCard properties not supported by QVersitContactImporter.
110
111 The supplied \a document is the container for the \a property. \a alreadyProcessed is true if
112 the QVersitContactImporter or another handler was successful in processing the property. If it is
113 false and the handler processes the property, it should be set to true to inform later handlers
114 that the property requires no further processing. \a contact holds the state of the contact
115 before the property was processed by the importer. \a updatedDetails is initially filled with a
116 list of details that the importer will update, and can be modified (by removing, modifying or
117 adding details to the list)
118 */
119
120/*!
121 \fn void QVersitContactImporterPropertyHandlerV2::documentProcessed(const QVersitDocument& document, QContact* contact)
122 Perform any final processing on the \a contact generated by the \a document. This can be
123 implemented by the handler to clear any internal state before moving onto the next document.
124
125 This function is called after all QVersitProperties have been handled by the
126 QVersitContactImporter.
127*/
128
129/*!
130 \class QVersitContactImporter
131 \brief The QVersitContactImporter class converts \l{QVersitDocument}{QVersitDocuments} to
132 \l{QContact}{QContacts}.
133
134 \ingroup versit
135 \inmodule QtVersit
136
137 This class is used to convert lists of \l{QVersitDocument}{QVersitDocuments} (which may be
138 produced by a QVersitReader) to lists of \l{QContact}{QContacts} (which may be saved into a
139 QContactManager. Unless there is an error, there is a one-to-one mapping between Versit
140 documents and QContacts. The importer can be extended by clients by associating resource
141 and property handlers.
142
143 Here is a simple example of how to use QVersitContactImporter:
144 \snippet qtversitdocsample/qtversitdocsample.cpp Import example
145
146 \section1 Extension via handlers
147
148 A \l QVersitResourceHandler is associated with the importer to supply the behaviour for saving
149 files to persistent storage. By default, this is set to a \l QVersitDefaultResourceHandler,
150 which does not save files to persistent storage. Note that photos found in vCards
151 are not saved to disk by default. If a full-sized image needs to be loaded from a URL
152 and persisted on disk, a custom QVersitResourceHandler should be supplied which implements this.
153
154 By associating a QVersitContactImporterPropertyHandlerV2 with the importer using
155 setPropertyHandler(), the client can pass in a handler to override the processing of properties
156 and/or handle properties that QVersitContactImporter doesn't support. Also, handlers can be
157 implicitly associated to an importer through the \l{Qt Versit Plugins}{handler plugin mechanism}.
158 The importer can be constructed with a profile, which gives hints about what kind of handlers
159 should be added to it. For example, the backup profile can be used to instruct the importer to
160 interpret properties that have been generated by a backup-profiled QVersitContactExporter. To
161 illustrate, a backup importer can be constructed with:
162 \code
163 QVersitContactImporter importer(QVersitContactHandlerFactory::ProfileBackup);
164 \endcode
165 For more details on how the backup plugin works, see \l{Qt Versit Plugins}
166
167 \section1 Importing categories
168 The importer imports the vCard CATEGORIES property by converting each category to a QContactTag.
169 Some managers may not have support for QContactTag, but instead support categorization using the
170 \l{QContactRelationship::HasMember}{HasMember} QContactRelationship along with contacts of type
171 \l{QContactType::TypeGroup}{TypeGroup}. For these backends, if the categorization information
172 needs to be retained through group relationships, extra work needs to be done to do the
173 conversion. Below is some example code that does this translation.
174
175 \snippet qtversitdocsample/qtversitdocsample.cpp Import relationship example
176
177 \sa QVersitDocument, QVersitProperty, QVersitResourceHandler, QVersitContactImporterPropertyHandlerV2
178 */
179
180/*!
181 \enum QVersitContactImporter::Error
182 This enum specifies an error that occurred during the most recent call to importDocuments()
183 \value NoError The most recent operation was successful
184 \value InvalidDocumentError One of the documents is not a vCard
185 \value EmptyDocumentError One of the documents is empty
186 */
187
188
189/*! Constructs a new importer */
190QVersitContactImporter::QVersitContactImporter()
191 : d(new QVersitContactImporterPrivate)
192{
193}
194
195/*!
196 * Constructs a new importer for the given \a profile. The profile strings should be one of those
197 * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Qt Versit
198 * Plugins}{Versit plugin}.
199 *
200 * The profile determines which plugins will be loaded to supplement the importer.
201 */
202QVersitContactImporter::QVersitContactImporter(const QString& profile)
203{
204 if (profile.isEmpty())
205 d = new QVersitContactImporterPrivate(QStringList());
206 else
207 d = new QVersitContactImporterPrivate(QStringList(profile));
208}
209
210/*!
211 * Constructs a new importer for the given \a profiles. The profile strings should be one of those
212 * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Qt Versit
213 * Plugins}{Versit plugin}.
214 *
215 * The profiles determine which plugins will be loaded to supplement the importer.
216 */
217QVersitContactImporter::QVersitContactImporter(const QStringList& profiles)
218 : d(new QVersitContactImporterPrivate(profiles))
219{
220}
221
222/*! Frees the memory used by the importer */
223QVersitContactImporter::~QVersitContactImporter()
224{
225 delete d;
226}
227
228/*!
229 * Converts \a documents into a corresponding list of QContacts. After calling this, the converted
230 * contacts can be retrieved by calling contacts().
231 * Returns true on success. If any of the documents cannot be imported as contacts (eg. they aren't
232 * vCards), false is returned and errorMap() will return a list describing the errors that occurred.
233 * The successfully imported documents will still be available via contacts().
234 *
235 * \sa contacts(), errorMap()
236 */
237bool QVersitContactImporter::importDocuments(const QList<QVersitDocument>& documents)
238{
239 int documentIndex = 0;
240 int contactIndex = 0;
241 d->mContacts.clear();
242 d->mErrors.clear();
243 bool ok = true;
244 foreach (const QVersitDocument& document, documents) {
245 QContact contact;
246 QVersitContactImporter::Error error;
247 if (d->importContact(versitDocument: document, contactIndex, contact: &contact, error: &error)) {
248 d->mContacts.append(t: contact);
249 contactIndex++;
250 } else {
251 d->mErrors.insert(akey: documentIndex, avalue: error);
252 ok = false;
253 }
254 documentIndex++;
255 }
256
257 return ok;
258}
259
260/*!
261 * Returns the contacts imported in the most recent call to importDocuments().
262 *
263 * \sa importDocuments()
264 */
265QList<QContact> QVersitContactImporter::contacts() const
266{
267 return d->mContacts;
268}
269
270/*!
271 * \obsolete
272 *
273 * Use \l errorMap() instead.
274 */
275QMap<int, QVersitContactImporter::Error> QVersitContactImporter::errors() const
276{
277 return d->mErrors;
278}
279
280/*!
281 * Returns the map of errors encountered in the most recent call to importDocuments(). The key is
282 * the index into the input list of documents and the value is the error that occurred on that
283 * document.
284 *
285 * \sa importDocuments()
286 */
287QMap<int, QVersitContactImporter::Error> QVersitContactImporter::errorMap() const
288{
289 return d->mErrors;
290}
291
292/*!
293 * \deprecated
294 * Sets \a handler to be the handler for processing QVersitProperties, or 0 to have no handler.
295 *
296 * Does not take ownership of the handler. The client should ensure the handler remains valid for
297 * the lifetime of the exporter. This function is used for version 1 handlers.
298 *
299 * Only one property handler can be set. If another property handler (of any version) was
300 * previously set, it will no longer be associated with the importer.
301 */
302void QVersitContactImporter::setPropertyHandler(QVersitContactImporterPropertyHandler* handler)
303{
304 d->mPropertyHandlerVersion = 1;
305 d->mPropertyHandler = handler;
306 d->mPropertyHandler2 = NULL;
307}
308
309/*!
310 * Sets \a handler to be the handler for processing QVersitProperties, or 0 to have no handler.
311 *
312 * Does not take ownership of the handler. The client should ensure the handler remains valid for
313 * the lifetime of the exporter. This function is used for version 2 and higher handlers.
314 *
315 * Only one property handler can be set. If another property handler (of any version) was
316 * previously set, it will no longer be associated with the importer.
317 */
318void QVersitContactImporter::setPropertyHandler(QVersitContactImporterPropertyHandlerV2* handler)
319{
320 d->mPropertyHandlerVersion = 2;
321 d->mPropertyHandler = 0;
322 d->mPropertyHandler2 = handler;
323}
324
325/*!
326 * \deprecated
327 * Gets the handler for processing QVersitProperties.
328 */
329QVersitContactImporterPropertyHandler* QVersitContactImporter::propertyHandler() const
330{
331 return d->mPropertyHandler;
332}
333
334/*!
335 * Sets \a handler to be the handler to save files with, or 0 to have no handler.
336 *
337 * Does not take ownership of the handler. The client should ensure the handler remains valid for
338 * the lifetime of the exporter.
339 */
340void QVersitContactImporter::setResourceHandler(QVersitResourceHandler* handler)
341{
342 d->mResourceHandler = handler;
343}
344
345/*!
346 * Returns the associated resource handler.
347 */
348QVersitResourceHandler* QVersitContactImporter::resourceHandler() const
349{
350 return d->mResourceHandler;
351}
352
353QT_END_NAMESPACE_VERSIT
354

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