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 "qvcardrestorehandler_p.h"
35
36#include <QtCore/qdatastream.h>
37#include <QtCore/qdatetime.h>
38#include <QtCore/qurl.h>
39
40#include "qversitproperty.h"
41
42/*
43 When these conditions are satisfied, QStringLiteral is implemented by
44 gcc's statement-expression extension. However, in this file it will
45 not work, because "statement-expressions are not allowed outside functions
46 nor in template-argument lists".
47
48 Fall back to the less-performant QLatin1String in this case.
49*/
50#if defined(QStringLiteral) && defined(QT_UNICODE_LITERAL_II) && defined(Q_CC_GNU) && !defined(Q_COMPILER_LAMBDA)
51# undef QStringLiteral
52# define QStringLiteral QLatin1String
53#endif
54
55QT_BEGIN_NAMESPACE_VERSIT
56
57const QString QVCardRestoreHandler::PropertyName(QStringLiteral("X-NOKIA-QCONTACTFIELD"));
58const QString QVCardRestoreHandler::DetailTypeParameter(QStringLiteral("DETAIL"));
59const QString QVCardRestoreHandler::FieldParameter(QStringLiteral("FIELD"));
60const QString QVCardRestoreHandler::DatatypeParameter(QStringLiteral("DATATYPE"));
61const QString QVCardRestoreHandler::DatatypeParameterVariant(QStringLiteral("VARIANT"));
62const QString QVCardRestoreHandler::DatatypeParameterDate(QStringLiteral("DATE"));
63const QString QVCardRestoreHandler::DatatypeParameterDateTime(QStringLiteral("DATETIME"));
64const QString QVCardRestoreHandler::DatatypeParameterTime(QStringLiteral("TIME"));
65const QString QVCardRestoreHandler::DatatypeParameterBool(QStringLiteral("BOOL"));
66const QString QVCardRestoreHandler::DatatypeParameterInt(QStringLiteral("INT"));
67const QString QVCardRestoreHandler::DatatypeParameterUInt(QStringLiteral("UINT"));
68const QString QVCardRestoreHandler::DatatypeParameterUrl(QStringLiteral("URL"));
69const QString QVCardRestoreHandler::GroupPrefix(QStringLiteral("G"));
70
71
72/*
73 * Returns a list of details generated from a Versit group.
74 */
75QList<QContactDetail> DetailGroupMap::detailsInGroup(const QString& groupName) const
76{
77 QList<int> detailIds = mDetailGroupName.keys(avalue: groupName);
78 QList<QContactDetail> details;
79 foreach (int detailId, detailIds) {
80 details << mDetailById[detailId];
81 }
82 return details;
83}
84
85/*
86 * Inserts the association between \a detail and \a groupName to the map.
87 * The detail must have a key (ie. have already been saved in a contact) and the group name must not
88 * be the empty string.
89 */
90void DetailGroupMap::insert(const QString& groupName, const QContactDetail& detail)
91{
92 Q_ASSERT(!groupName.isEmpty());
93 mDetailGroupName[detail.key()] = groupName;
94 mDetailById[detail.key()] = detail;
95}
96
97/*
98 * Replaces the detail currently in the map with \a detail.
99 * The detail must have a key (ie. have already been saved in a contact).
100 */
101void DetailGroupMap::update(const QContactDetail& detail)
102{
103 Q_ASSERT(detail.key());
104 mDetailById[detail.key()] = detail;
105}
106
107/*!
108 * Removes details and groups from the map.
109 */
110void DetailGroupMap::clear()
111{
112 mDetailGroupName.clear();
113 mDetailById.clear();
114}
115
116
117
118
119bool QVCardRestoreHandler::propertyProcessed(
120 const QVersitProperty& property,
121 QList<QContactDetail>* updatedDetails)
122{
123 bool success = false;
124 QString group;
125 if (!property.groups().isEmpty())
126 group = property.groups().first();
127 if (property.name() == PropertyName) {
128 if (property.groups().size() != 1)
129 return false;
130 QMultiHash<QString, QString> parameters = property.parameters();
131 QContactDetail::DetailType detailType = QContactDetail::DetailType(parameters.value(akey: DetailTypeParameter).toUInt());
132 QString fieldName = parameters.value(akey: FieldParameter);
133 // Find a detail previously seen with the same definitionName, which was generated from
134 // a property from the same group
135 QContactDetail detail(detailType);
136 foreach (const QContactDetail& previousDetail, mDetailGroupMap.detailsInGroup(group)) {
137 if (previousDetail.type() == detailType) {
138 detail = previousDetail;
139 }
140 }
141 // If not found, it's a new empty detail with the definitionName set.
142
143 detail.setValue(field: fieldName.toInt(), value: deserializeValue(property));
144
145 // Replace the equivalent detail in updatedDetails with the new one
146 QMutableListIterator<QContactDetail> it(*updatedDetails);
147 while (it.hasNext()) {
148 if (it.next().key() == detail.key()) {
149 it.remove();
150 break;
151 }
152 }
153 updatedDetails->append(t: detail);
154 success = true;
155 }
156 if (!group.isEmpty()) {
157 // Keep track of which details were generated from which Versit groups
158 foreach (const QContactDetail& detail, *updatedDetails) {
159 mDetailGroupMap.insert(groupName: group, detail);
160 }
161 }
162 return success;
163}
164
165QVariant QVCardRestoreHandler::deserializeValue(const QVersitProperty& property)
166{
167 // Import the field
168 if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterVariant)) {
169 // The value was stored as a QVariant serialized in a QByteArray
170 QDataStream stream(property.variantValue().toByteArray());
171 QVariant value;
172 stream >> value;
173 return value;
174 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterDate)) {
175 // The value was a QDate serialized as a string
176 return QDate::fromString(s: property.value(), f: Qt::ISODate);
177 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterTime)) {
178 // The value was a QTime serialized as a string
179 return QTime::fromString(s: property.value(), f: Qt::ISODate);
180 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterDateTime)) {
181 // The value was a QDateTime serialized as a string
182 return QDateTime::fromString(s: property.value(), f: Qt::ISODate);
183 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterBool)) {
184 // The value was a bool serialized as a string
185 return property.value().toInt() != 0;
186 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterInt)) {
187 // The value was an int serialized as a string
188 return property.value().toInt();
189 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterUInt)) {
190 // The value was a uint serialized as a string
191 return property.value().toUInt();
192 } else if (property.parameters().contains(key: DatatypeParameter, value: DatatypeParameterUrl)) {
193 // The value was a QUrl serialized as a string
194 return QUrl(property.value());
195 } else {
196 // The value was stored as a QString or QByteArray
197 return property.variantValue();
198 }
199}
200
201void QVCardRestoreHandler::documentProcessed()
202{
203 mDetailGroupMap.clear();
204}
205
206QT_END_NAMESPACE_VERSIT
207

source code of qtpim/src/versit/qvcardrestorehandler_p.cpp