src/versit/qversitcontactexporter.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     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 }