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 "backupvcardhandler.h"
35
36#include <QtCore/qdatastream.h>
37#include <QtCore/qdatetime.h>
38#include <QtCore/qvariant.h>
39#include <QtCore/qurl.h>
40
41#include <QtContacts/qcontact.h>
42#include <QtContacts/qcontactdetail.h>
43#include <QtContacts/qcontactextendeddetail.h>
44
45#include <QtVersit/qversitdocument.h>
46#include <QtVersit/qversitproperty.h>
47#include <QtVersit/private/qvcardrestorehandler_p.h>
48
49/*
50 When these conditions are satisfied, QStringLiteral is implemented by
51 gcc's statement-expression extension. However, in this file it will
52 not work, because "statement-expressions are not allowed outside functions
53 nor in template-argument lists".
54
55 Fall back to the less-performant QLatin1String in this case.
56*/
57#if defined(QStringLiteral) && defined(QT_UNICODE_LITERAL_II) && defined(Q_CC_GNU) && !defined(Q_COMPILER_LAMBDA)
58# undef QStringLiteral
59# define QStringLiteral QLatin1String
60#endif
61
62QTCONTACTS_USE_NAMESPACE
63
64QT_BEGIN_NAMESPACE_VERSIT
65
66/* See QVersitContactImporter::createBackupHandler() */
67class BackupVCardHandler : public QVersitContactHandler
68{
69public:
70 BackupVCardHandler();
71 void propertyProcessed(const QVersitDocument& document,
72 const QVersitProperty& property,
73 const QContact& contact,
74 bool* alreadyProcessed,
75 QList<QContactDetail>* updatedDetails);
76 void documentProcessed(const QVersitDocument& document,
77 QContact* contact);
78 void detailProcessed(const QContact& contact,
79 const QContactDetail& detail,
80 const QVersitDocument& document,
81 QSet<int>* processedFields,
82 QList<QVersitProperty>* toBeRemoved,
83 QList<QVersitProperty>* toBeAdded);
84 void contactProcessed(const QContact& contact,
85 QVersitDocument* document);
86
87private:
88 static void serializeValue(QVersitProperty* property, const QVariant& value);
89 DetailGroupMap mDetailGroupMap; // remembers which details came from which groups
90 int mDetailNumber;
91};
92
93const QString PropertyName(QStringLiteral("X-NOKIA-QCONTACTFIELD"));
94const QString DetailTypeParameter(QStringLiteral("DETAIL"));
95const QString FieldParameter(QStringLiteral("FIELD"));
96const QString DatatypeParameter(QStringLiteral("DATATYPE"));
97const QString DatatypeParameterVariant(QStringLiteral("VARIANT"));
98const QString DatatypeParameterDate(QStringLiteral("DATE"));
99const QString DatatypeParameterDateTime(QStringLiteral("DATETIME"));
100const QString DatatypeParameterTime(QStringLiteral("TIME"));
101const QString DatatypeParameterBool(QStringLiteral("BOOL"));
102const QString DatatypeParameterInt(QStringLiteral("INT"));
103const QString DatatypeParameterUInt(QStringLiteral("UINT"));
104const QString DatatypeParameterUrl(QStringLiteral("URL"));
105const QString GroupPrefix(QStringLiteral("G"));
106
107QSet<QString> BackupVCardHandlerFactory::profiles() const
108{
109 QSet<QString> retval;
110 retval.insert(value: QVersitContactHandlerFactory::ProfileBackup());
111 return retval;
112}
113
114QString BackupVCardHandlerFactory::name() const
115{
116 return QStringLiteral("org.qt-project.Qt.BackupVCardHandlerFactory");
117}
118
119int BackupVCardHandlerFactory::index() const
120{
121 // Prefer to run this plugin last.
122 return -1;
123}
124
125QVersitContactHandler* BackupVCardHandlerFactory::createHandler() const
126{
127 return new BackupVCardHandler();
128}
129
130QStringList BackupVCardHandlerFactory::keys() const
131{
132 return QStringList() << name();
133}
134
135
136BackupVCardHandler::BackupVCardHandler()
137 : mDetailNumber(0)
138{
139}
140
141void BackupVCardHandler::propertyProcessed(
142 const QVersitDocument& document,
143 const QVersitProperty& property,
144 const QContact& contact,
145 bool* alreadyProcessed,
146 QList<QContactDetail>* updatedDetails)
147{
148 Q_UNUSED(document)
149 Q_UNUSED(property)
150 Q_UNUSED(contact)
151 Q_UNUSED(alreadyProcessed)
152 Q_UNUSED(updatedDetails)
153}
154
155void BackupVCardHandler::documentProcessed(
156 const QVersitDocument& document,
157 QContact* contact)
158{
159 Q_UNUSED(document)
160 Q_UNUSED(contact)
161}
162
163void BackupVCardHandler::detailProcessed(
164 const QContact& contact,
165 const QContactDetail& detail,
166 const QVersitDocument& document,
167 QSet<int>* processedFields,
168 QList<QVersitProperty>* toBeRemoved,
169 QList<QVersitProperty>* toBeAdded)
170{
171 Q_UNUSED(contact)
172 Q_UNUSED(document)
173 Q_UNUSED(toBeRemoved)
174 if (detail.accessConstraints().testFlag(flag: QContactDetail::ReadOnly))
175 return;
176 QMap<int, QVariant> fields = detail.values();
177 // fields from the same detail have the same group so the importer can collate them
178 QString detailGroup = GroupPrefix + QString::number(mDetailNumber++);
179 int toBeAddedCount = toBeAdded->count();
180 bool propertiesSynthesized = false;
181 for (QMap<int, QVariant>::const_iterator it = fields.constBegin(); it != fields.constEnd(); it++) {
182 if (!processedFields->contains(value: it.key()) && !it.value().toString().isEmpty()) {
183 // Generate a property for the unknown field
184 QVersitProperty property;
185 property.setGroups(QStringList(detailGroup));
186 property.setName(PropertyName);
187 property.insertParameter(name: DetailTypeParameter, value: QString::number(detail.type()));
188 property.insertParameter(name: FieldParameter, value: QString::number(it.key()));
189
190 serializeValue(property: &property, value: it.value());
191
192 toBeAdded->append(t: property);
193 propertiesSynthesized = true;
194 processedFields->insert(value: it.key());
195 }
196 }
197 if (propertiesSynthesized) {
198 // We need to group the already-generated properties with the newly synthesized ones
199 for (int i = 0; i < toBeAddedCount; i++) {
200 QVersitProperty& property = (*toBeAdded)[i];
201 property.setGroups(property.groups() << detailGroup);
202 }
203 }
204}
205
206void BackupVCardHandler::serializeValue(QVersitProperty* property, const QVariant& value)
207{
208 // serialize the value
209 if (value.type() == QVariant::String
210 || value.type() == QVariant::ByteArray) {
211 // store QStrings and QByteArrays as-is
212 property->setValue(value);
213 } else if (value.type() == QVariant::Date) {
214 // Store a QDate as a string
215 QString valueString(value.toDate().toString(format: Qt::ISODate));
216 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterDate);
217 property->setValue(valueString);
218 } else if (value.type() == QVariant::Time) {
219 // Store a QTime as a string
220 QString valueString(value.toTime().toString(f: Qt::ISODate));
221 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterTime);
222 property->setValue(valueString);
223 } else if (value.type() == QVariant::DateTime) {
224 // Store a QDateTime as a string
225 QString valueString(value.toDateTime().toString(format: Qt::ISODate));
226 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterDateTime);
227 property->setValue(valueString);
228 } else if (value.type() == QVariant::Bool) {
229 // Store an int as a string
230 QString valueString(QString::number(value.toBool() ? 1 : 0));
231 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterBool);
232 property->setValue(valueString);
233 } else if (value.type() == QVariant::Int) {
234 // Store an int as a string
235 QString valueString(QString::number(value.toInt()));
236 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterInt);
237 property->setValue(valueString);
238 } else if (value.type() == QVariant::UInt) {
239 // Store a uint as a string
240 QString valueString(QString::number(value.toUInt()));
241 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterUInt);
242 property->setValue(valueString);
243 } else if (value.type() == QVariant::Url) {
244 // Store a QUrl as a string
245 QString valueString(value.toUrl().toString());
246 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterUrl);
247 property->setValue(valueString);
248 } else {
249 // Store other types by serializing the QVariant in a QByteArray
250 QByteArray valueBytes;
251 QDataStream stream(&valueBytes, QIODevice::WriteOnly);
252 stream << value;
253 property->insertParameter(name: DatatypeParameter, value: DatatypeParameterVariant);
254 property->setValue(valueBytes);
255 }
256}
257
258void BackupVCardHandler::contactProcessed(
259 const QContact& contact,
260 QVersitDocument* document)
261{
262 Q_UNUSED(contact)
263 Q_UNUSED(document)
264 mDetailNumber = 0;
265}
266
267#include "moc_backupvcardhandler.cpp"
268
269QT_END_NAMESPACE_VERSIT
270

source code of qtpim/src/plugins/versit/backuphandler/backupvcardhandler.cpp