src/versit/qversitcontactexporter.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitcontactexporter.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,381 @@
+/****************************************************************************
+**
+** 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 "qvcardbackuphandlers_p.h"
+#include "qmobilityglobal.h"
+
+#include <qcontact.h>
+#include <qcontactdetail.h>
+
+QTM_USE_NAMESPACE
+
+/*!
+  \deprecated
+  \class QVersitContactExporterDetailHandler
+  \brief The QVersitContactExporterDetailHandler class is an interface for clients wishing to
+  implement custom export behaviour for certain contact details.
+
+  This interface is replaced by QVersitContactExporterDetailHandlerV2.
+  \ingroup versit
+
+  \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 clients wishing to
+  implement custom export behaviour for certain contact details.
+
+  This interface supercedes QVersitContactImporterPropertyHandler.
+
+  \ingroup versit
+
+  \sa QVersitContactExporter
+ */
+
+/*!
+  \fn QVersitContactExporterDetailHandlerV2::~QVersitContactExporterDetailHandlerV2()
+  Frees any memory in use by this handler.
+ */
+
+/*!
+  \fn void QVersitContactExporterDetailHandlerV2::detailProcessed(const QContact& contact, const QContactDetail& detail, const QSet<QString>& processedFields, const QVersitDocument& document, 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 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.
+
+  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.
+*/
+
+/*!
+  \fn int QVersitContactExporterDetailHandlerV2::version() const
+  Returns the version of the handler.  Currently, always returns 2.
+*/
+
+/*!
+  \class QVersitContactExporter
+  \brief The QVersitContactExporter class converts \l {QContact}{QContacts} into
+  \l {QVersitDocument}{QVersitDocuments}.
+  \ingroup versit
+
+  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.
+
+  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.  A "backup" handler is provided by
+  QVersitContactExporterDetailHandlerV2::createBackupHandler(), which serializes any details
+  that the standard QVersitContactExporter doesn't support to the vCard.
+
+
+  An example usage of QVersitContactExporter:
+  \snippet ../../doc/src/snippets/qtversitdocsample/qtversitdocsample.cpp Export example
+
+  \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
+
+  \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 and returns a detail handler that encodes all details not handled by the base exporter.
+  The caller is responsible for deleting the object.
+
+  This handler encodes all writable details that the exporter doesn't recognise.  The format it uses
+  to encode the detail is as follows:
+  \list
+  \o All generated properties will have the name X-NOKIA-QCONTACTFIELD
+  \o All generated properties will have a single Versit group, and all properties generated from a
+     single detail will have the same group.
+  \o All generated properties will have at least the parameters DETAIL, which holds the definition
+     name of the QContactDetail from which it was generated, and FIELD, which holds the name of the
+     field within the detail from which it was generated.
+  \o If the field is of type QString or QByteArray, the property's value is set directly to the
+     value of the field.  (For a QByteArray value, the QVersitWriter will base-64 encode it.)
+  \o If the field is of type bool, int, uint, QDate, QTime, QDateTime or QUrl a the property's
+     value is set to a string representation of the field.  A parameter DATATYPE is added to the
+     property with value BOOL, INT, UINT, DATE, TIME or DATETIME depending on the type.
+  \o If the field is of some other type, the field value is encoded to a QByteArray via QDataStream
+     (and the resulting byte array is base-64 encoded by the QVersitWriter).  In this case, the
+     parameter DATATYPE=VARIANT is added to the Versit property.
+  \endlist
+
+  For example, a detail with definition name "Pet" and fields "Name"="Rex" and
+  "Age"=(int)14 will be exported to the vCard properties:
+  \code
+  G0.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Name:Rex
+  G0.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Age;DATATYPE=INT:14
+  \endcode
+
+  And the next detail (say, "Pet" with a field "Name"="Molly" will generate:
+  \code
+  G1.X-NOKIA-QCONTACTFIELD;DETAIL=Pet;FIELD=Name:Molly
+  \endcode
+
+  The properties produced by this class can be imported by the importer "backup" property handler
+  (created by QVersitContactImporterPropertyHandlerV2::createBackupHandler()) to reproduce the
+  original \l{QContactDetail}{QContactDetails}.
+
+  Clients wishing to implement their own detail handler and also benefit from the functionality of
+  the backup handler can use this function to construct one, and wrap a custom
+  QVersitContactExporterDetailHandlerV2 around it.  In the implementation of detailProcessed and
+  contactProcessed, the respective functions in the backup handler should be called as the last
+  step (ensuring the arguments are correctly updated and passed through).
+ */
+QVersitContactExporterDetailHandlerV2* QVersitContactExporterDetailHandlerV2::createBackupHandler() {
+    return new QVCardExporterBackupHandler;
+}
+
+/*!
+ * Constructs a new contact exporter
+ */
+QVersitContactExporter::QVersitContactExporter()
+    : d(new QVersitContactExporterPrivate())
+{
+}
+
+/*!
+ * 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
+ * errors() will return a list describing the errors that occurred.  The successfully exported
+ * documents will still be available via documents().
+ */
+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);
+        QVersitContactExporter::Error error;
+        if (d->exportContact(contact, versitDocument, &error)) {
+            d->mDocuments.append(versitDocument);
+        } else {
+            d->mErrors.insert(contactIndex, error);
+            ok = false;
+        }
+        contactIndex++;
+    }
+
+    return ok;
+}
+
+/*!
+ * Returns the documents exported in the most recent call to exportContacts().
+ *
+ * \sa exportContacts()
+ */
+QList<QVersitDocument> QVersitContactExporter::documents() const
+{
+    return d->mDocuments;
+}
+
+/*!
+ * 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::errors() 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)
+{
+    if (handler)
+        d->mDetailHandlerVersion = handler->version();
+    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;
+}