summaryrefslogtreecommitdiffstats
path: root/src/versit/qversitcontactexporter.cpp
blob: 2dfaad47d2a9c6344f5e44d3e3ced486b15191c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include "qversitcontactexporter.h"
#include "qversitcontactexporter_p.h"
#include "qmobilityglobal.h"

#include <qcontact.h>
#include <qcontactdetail.h>

QTM_USE_NAMESPACE

/*!
  \deprecated
  \class QVersitContactExporterDetailHandler
  \brief The QVersitContactExporterDetailHandler class is the legacy interface for clients wishing
  to implement custom export behaviour for certain contact details.

  This interface is replaced by QVersitContactExporterDetailHandlerV2.  For general information on
  extending Qt Versit, see the document on \l{Versit Plugins}.


  \sa QVersitContactExporter
 */

/*!
  \fn QVersitContactExporterDetailHandler::~QVersitContactExporterDetailHandler()
  Frees any memory in use by this handler.
 */

/*!
  \fn bool QVersitContactExporterDetailHandler::preProcessDetail(const QContact& contact, const QContactDetail& detail, QVersitDocument* document)
  Process \a detail and update \a document with the corresponding QVersitProperty(s).
  \a contact provides the context within which the detail was found.

  Returns true if the detail has been handled and requires no further processing, false otherwise.

  This function is called on every QContactDetail encountered during an export.  Supply this
  function and return true to implement custom export behaviour.
 */

/*!
  \fn bool QVersitContactExporterDetailHandler::postProcessDetail(const QContact& contact, const QContactDetail& detail, bool alreadyProcessed, QVersitDocument* document)
  Process \a detail and update \a document with the corresponding QVersitProperty(s).
  \a contact provides the context within which the detail was found.
  \a alreadyProcessed is true if the detail has already been processed either by
  \l preProcessDetail() or by QVersitContactExporter itself.

  Returns true if the detail has been handled, false otherwise.

  This function is called on every \l QContactDetail encountered during an export.  This can be
  used to implement support for QContactDetails not supported by QVersitContactExporter.
 */

/*!
  \class QVersitContactExporterDetailHandlerV2
  \brief The QVersitContactExporterDetailHandlerV2 class is an interface for specifying custom
  export behaviour for certain contact details.
  \ingroup versit-extension
  \inmodule QtVersit

  This interface supercedes QVersitContactExporterDetailHandler.  For general information on
  extending Qt Versit, see the document on \l{Versit Plugins}.


  \sa QVersitContactExporter
 */

/*!
  \fn QVersitContactExporterDetailHandlerV2::~QVersitContactExporterDetailHandlerV2()
  Frees any memory in use by this handler.
 */

/*!
  \fn void QVersitContactExporterDetailHandlerV2::detailProcessed(const QContact& contact, const QContactDetail& detail, const QVersitDocument& document, QSet<QString>* processedFields, QList<QVersitProperty>* toBeRemoved, QList<QVersitProperty>* toBeAdded)

  Process \a detail and provide a list of updated \l{QVersitProperty}{QVersitProperties} by
  modifying the \a toBeRemoved and \a toBeAdded lists.  

  This function is called on every QContactDetail encountered during an export, after the detail has
  been processed by the QVersitContactExporter.  An implementation of this function can be made to
  provide support for QContactDetails not supported by QVersitContactExporter.

  The supplied \a contact is the container for the \a detail.  \a processedFields contains a list of
  fields in the \a detail that were considered by the QVersitContactExporter or another handler in
  processing the detail.  \a document holds the state of the document before the detail was
  processed by the exporter.
  
  \a toBeRemoved and \a toBeAdded are initially filled with a list of properties that the exporter
  will remove from and add to the document.  These lists can be modified (by removing, modifying or
  adding properties) by the handler to control the changes that will actually be made to the
  document.  If a property is to be modified in the document, the old version will appear in the
  \a toBeRemoved list and the new version will appear in the \a toBeAdded list.  When the handler
  uses a field from the detail, it should update the processedFields set to reflect this to inform
  later handlers that the field has already been processed.

  After the handler returns control back to the exporter, the properties in the \a toBeRemoved
  list will be removed and the properties in the \a toBeAdded list will be appended to the document.
 */

/*!
  \fn void QVersitContactExporterDetailHandlerV2::contactProcessed(const QContact& contact, QVersitDocument* document)
  Perform any final processing on the \a document generated by the \a contact.  This can be
  implemented by the handler to clear any internal state before moving onto the next contact.

  This function is called after all QContactDetails have been handled by the
  QVersitContactExporter.
*/

/*!
  \class QVersitContactExporter
  \brief The QVersitContactExporter class converts \l {QContact}{QContacts} into
  \l {QVersitDocument}{QVersitDocuments}.
  \ingroup versit
  \inmodule QtVersit

  This class is used to convert lists of \l {QContact}{QContacts} (which may be stored in a
  QContactManager) into lists of \l {QVersitDocument}{QVersitDocuments} (which may be written to
  an I/O device using QVersitReader.  Unless there is an error, there is a one-to-one mapping
  between contacts and Versit documents.  The exporter can be extended by clients by associating
  resource and detail handlers.

  Here is a simple example of how to use QVersitContactExporter:
  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export example

  \section1 Extension via handlers

  A \l QVersitResourceHandler is associated with the exporter to supply the behaviour for loading
  files from persistent storage.  By default, this is set to a \l QVersitDefaultResourceHandler,
  which supports basic resource loading from the file system.  An alternative resource handler
  can be specified with setResourceHandler().

  By associating a \l QVersitContactExporterDetailHandlerV2 with the exporter using
  setDetailHandler(), the client can pass in a handler to override the processing of details and/or
  handle details that QVersitContactExporter doesn't support.  Also, handlers can be implicitly
  associated to an exporter through the \l{Versit Plugins}{handler plugin mechanism}.  The exporter
  can be constructed with a profile, which gives hints about what kind of handlers should be added
  to it.  For example, the backup profile can be used to instruct the exporter to encode any unknown
  details in the vCard such that it can be reconstructed later (a QVersitContactImporter constructed
  under the backup profile can be used to decode it).  To illustrate, a backup exporter can be
  constructed with:
  \code
  QVersitContactExporter exporter(QVersitContactHandlerFactory::ProfileBackup);
  \endcode
  For more details on how the backup plugin works, see \l{Versit Plugins}

  \section1 Exporting group relationships
  The exporter does not handle QContactRelationships at all.

  Some managers use the \l{QContactRelationship::HasMember}{HasMember} QContactRelationship along
  with contacts of type \l{QContactType::TypeGroup}{TypeGroup} to indicate categorization of
  contacts.  In vCard, categorization is represented by the CATEGORIES property, which has
  semantics most similar to the QContactTag detail.  For contact manager backends that supports
  groups but not QContactTag, if the categorization information needs to be retained through
  CATEGORIES vCard properties, extra work can be done to convert from group relationships to
  QContactTag before passing the contact list to the exporter.  Below is some example code that
  does this translation.

  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export relationship example

  \section1 Other implementation notes

  Some Symbian and Android devices do not properly handle the \c FN vCard property.  If a
  CustomLabel is set on a contact and this class is used to generate a vCard, the receiving device
  might display this label in an unexpected field (eg. Last Name).

  The vCard specification requires the \c FN property to be present.  However, because of this
  interoperability issue, Qt Versit only generates an FN property if a CustomLabel is set.

  \sa QVersitDocument, QVersitProperty, QVersitResourceHandler, QVersitContactExporterDetailHandlerV2
 */

/*!
  \enum QVersitContactExporter::Error
  This enum specifies an error that occurred during the most recent call to exportContacts()
  \value NoError The most recent operation was successful
  \value EmptyContactError One of the contacts was empty
  \value NoNameError One of the contacts has no QContactName field
  */


/*!
 * Constructs a new contact exporter
 */
QVersitContactExporter::QVersitContactExporter()
    : d(new QVersitContactExporterPrivate())
{
}

/*!
 * Constructs a new exporter for the given \a profile.  The profile strings should be one of those
 * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Versit
 * Plugin}{Versit plugin}.
 *
 * The profile determines which plugins will be loaded to supplement the exporter.
 */
QVersitContactExporter::QVersitContactExporter(const QString& profile)
{
    if (profile.isEmpty())
       d = new QVersitContactExporterPrivate(QStringList());
    else
       d = new QVersitContactExporterPrivate(QStringList() << profile);
}

/*!
 * Constructs a new exporter for the given \a profiles.  The profile strings should be one of those
 * defined by QVersitContactHandlerFactory, or a value otherwise agreed to by a \l{Versit
 * Plugin}{Versit plugin}.
 *
 * The profiles determine which plugins will be loaded to supplement the exporter.
 */
QVersitContactExporter::QVersitContactExporter(const QStringList& profiles)
    : d(new QVersitContactExporterPrivate(profiles))
{
}

/*!
 * Frees any memory in use by this contact exporter.
 */
QVersitContactExporter::~QVersitContactExporter()
{
    delete d;
}

/*!
 * Converts \a contacts into a list of corresponding QVersitDocuments, using the format given by
 * \a versitType.
 *
 * Returns true on success.  If any of the contacts could not be exported, false is returned and
 * errorMap() will return a list describing the errors that occurred.  The successfully exported
 * documents will still be available via documents().
 *
 * \sa documents(), errorMap()
 */
bool QVersitContactExporter::exportContacts(
    const QList<QContact>& contacts,
    QVersitDocument::VersitType versitType)
{
    int contactIndex = 0;
    d->mDocuments.clear();
    d->mErrors.clear();
    bool ok = true;
    foreach (const QContact& contact, contacts) {
        QVersitDocument versitDocument;
        versitDocument.setType(versitType);
        versitDocument.setComponentType(QLatin1String("VCARD"));
        d->exportContact(contact, versitDocument);
        d->mDocuments.append(versitDocument);
        contactIndex++;
    }

    return ok;
}

/*!
 * Returns the documents exported in the most recent call to exportContacts().
 *
 * \sa exportContacts()
 */
QList<QVersitDocument> QVersitContactExporter::documents() const
{
    return d->mDocuments;
}

/*!
 * \obsolete
 *
 * Use \l errorMap() instead.
 */
QMap<int, QVersitContactExporter::Error> QVersitContactExporter::errors() const
{
    return d->mErrors;
}

/*!
 * Returns the map of errors encountered in the most recent call to exportContacts().  The key is
 * the index into the input list of contacts and the value is the error that occurred on that
 * contact.
 *
 * \sa exportContacts()
 */
QMap<int, QVersitContactExporter::Error> QVersitContactExporter::errorMap() const
{
    return d->mErrors;
}

/*!
 * \deprecated
 * Sets \a handler to be the handler for processing QContactDetails, or 0 to have no handler.
 *
 * Does not take ownership of the handler.  The client should ensure the handler remains valid for
 * the lifetime of the exporter.  This function is used for version 1 handlers.
 *
 * Only one detail handler can be set.  If another detail handler (of any version) was
 * previously set, it will no longer be associated with the exporter.
 */
void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandler* handler)
{
    d->mDetailHandlerVersion = 1;
    d->mDetailHandler = handler;
    d->mDetailHandler2 = 0;
}

/*!
 * Sets \a handler to be the handler for processing QContactDetails, or 0 to have no handler.
 *
 * Does not take ownership of the handler.  The client should ensure the handler remains valid for
 * the lifetime of the exporter.  This function is used for version 2 and higher handlers.
 *
 * Only one detail handler can be set.  If another detail handler (of any version) was
 * previously set, it will no longer be associated with the exporter.
 */
void QVersitContactExporter::setDetailHandler(QVersitContactExporterDetailHandlerV2* handler)
{
    d->mDetailHandlerVersion = 2;
    d->mDetailHandler = 0;
    d->mDetailHandler2 = handler;
}

/*!
 * \deprecated
 * Gets the handler for processing QContactDetails.
 */
QVersitContactExporterDetailHandler* QVersitContactExporter::detailHandler() const
{
    return d->mDetailHandler;
}

/*!
 * Sets \a handler to be the handler to load files with, or 0 to have no handler.
 *
 * Does not take ownership of the handler.  The client should ensure the handler remains valid for
 * the lifetime of the exporter.
 */
void QVersitContactExporter::setResourceHandler(QVersitResourceHandler* handler)
{
    d->mResourceHandler = handler;
}

/*!
 * Returns the associated resource handler.
 */
QVersitResourceHandler* QVersitContactExporter::resourceHandler() const
{
    return d->mResourceHandler;
}