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 | |
37 | QT_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 */ |
190 | QVersitContactImporter::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 | */ |
202 | QVersitContactImporter::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 | */ |
217 | QVersitContactImporter::QVersitContactImporter(const QStringList& profiles) |
218 | : d(new QVersitContactImporterPrivate(profiles)) |
219 | { |
220 | } |
221 | |
222 | /*! Frees the memory used by the importer */ |
223 | QVersitContactImporter::~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 | */ |
237 | bool 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 | */ |
265 | QList<QContact> QVersitContactImporter::contacts() const |
266 | { |
267 | return d->mContacts; |
268 | } |
269 | |
270 | /*! |
271 | * \obsolete |
272 | * |
273 | * Use \l errorMap() instead. |
274 | */ |
275 | QMap<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 | */ |
287 | QMap<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 | */ |
302 | void 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 | */ |
318 | void 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 | */ |
329 | QVersitContactImporterPropertyHandler* 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 | */ |
340 | void QVersitContactImporter::setResourceHandler(QVersitResourceHandler* handler) |
341 | { |
342 | d->mResourceHandler = handler; |
343 | } |
344 | |
345 | /*! |
346 | * Returns the associated resource handler. |
347 | */ |
348 | QVersitResourceHandler* QVersitContactImporter::resourceHandler() const |
349 | { |
350 | return d->mResourceHandler; |
351 | } |
352 | |
353 | QT_END_NAMESPACE_VERSIT |
354 | |