1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtVersit module of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
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 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include <qversitproperty.h>
43
#include "qversitproperty_p.h"
45
#include <QStringList>
48
QT_BEGIN_NAMESPACE_VERSIT
51
\class QVersitProperty
52
\brief The QVersitProperty class stores the name, value, groups and parameters of a Versit property.
56
A vCard is represented in abstract form as a QVersitDocument that consists of a number of
57
properties such as a name (N), a telephone number (TEL) and an email address (EMAIL), for
58
instance. Each of these properties is stored as an instance of a QVersitProperty in a
61
A QVersitProperty consists of a list of groups, a name, a list of parameters (key/value pairs),
64
The value of a QVersitProperty is stored as a QVariant and should always be one of four types:
65
QString for textual values, QByteArray for binary data (eg. images), QStringList for structured
66
textual data, or QVersitDocument for nested documents. The \l QVersitReader will parse Versit
67
properties and assign the correct type of object to the property value. The \l QVersitWriter will
68
serialize objects of these types correctly into the (text-based) Versit format.
70
For example, a property might appear in a vCard as:
72
ADR;TYPE=home,postal:;;123 Main Street;Any Town;CA;91921-1234
74
This would be stored as a QVersitProperty with the name \tt{ADR} and two parameters (both named
75
\tt{TYPE} and with values \tt{home} and \tt{postal} respectively. The value of the
76
QVersitProperty is a QStringList with six strings, and the valueType is CompoundType.
78
QVersitProperty supports implicit sharing. The property name and parameter names of a
79
QVersitProperty are converted to upper-case when they are stored to a QVersitProperty.
85
\enum QVersitProperty::ValueType
86
Describes the type of data held in the property's value.
88
The vCard and iCalendar specifications allows a property value to hold a string, binary data, or a
89
nested document. String values can either be unstructured or structured. Structured strings can
90
be either of compound type or list type. A compound value is one that is delimited by semicolons,
91
allows empty components, and has a property-specific cardinality and ordering. A list value is
92
one that is delimited by commas, does not have empty components, and has no restrictions on
93
cardinality or ordering.
95
\value PlainType The property value holds an unstructured string and can be retrieved with
96
QVersitProperty::value()
97
\value CompoundType The property value holds a compound string and can be retrieved with
98
QVersitProperty::value<QStringList>()
99
\value ListType The property value holds a list of strings and can be retrieved with
100
QVersitProperty::value<QStringList>()
101
\value BinaryType The property value holds a binary value and can be retrieved with
102
QVersitProperty::value<QByteArray>()
103
\value VersitDocumentType The property value holds a nested Versit document and can be retrieved
104
\value PreformattedType The property value holds a string that represents exactly the text for
105
the property in the vCard file, bar line-wrapping. That is, if the property were to be written
106
to file it should be written as-is, with no backslash escaping.
109
/*! Constructs a new empty property */
110
QVersitProperty::QVersitProperty() : d(new QVersitPropertyPrivate())
114
/*! Constructs a property that is a copy of \a other */
115
QVersitProperty::QVersitProperty(const QVersitProperty& other) : d(other.d)
119
/*! Frees the memory used by the property */
120
QVersitProperty::~QVersitProperty()
124
/*! Assigns this property to \a other */
125
QVersitProperty& QVersitProperty::operator=(const QVersitProperty& other)
132
/*! Returns true if this is equal to \a other; false otherwise. */
133
bool QVersitProperty::operator==(const QVersitProperty& other) const
135
bool equal = d->mGroups == other.d->mGroups &&
136
d->mName == other.d->mName &&
137
d->mParameters == other.d->mParameters &&
138
d->mValueType == other.d->mValueType;
142
// QVariant doesn't support == on QVersitDocuments - do it manually
143
if (d->mValue.userType() == qMetaTypeId<QVersitDocument>())
144
return other.d->mValue.userType() == qMetaTypeId<QVersitDocument>()
145
&& d->mValue.value<QVersitDocument>() == other.d->mValue.value<QVersitDocument>();
147
return d->mValue == other.d->mValue;
150
/*! Returns true if this is not equal to \a other; false otherwise. */
151
bool QVersitProperty::operator!=(const QVersitProperty& other) const
153
return !(*this == other);
156
/*! Returns the hash value for \a key. */
157
uint qHash(const QVersitProperty &key)
159
uint hash = QT_PREPEND_NAMESPACE(qHash)(key.name()) + QT_PREPEND_NAMESPACE(qHash)(key.value());
160
foreach (const QString& group, key.groups()) {
161
hash += QT_PREPEND_NAMESPACE(qHash)(group);
163
QHash<QString,QString>::const_iterator it = key.parameters().constBegin();
164
QHash<QString,QString>::const_iterator end = key.parameters().constEnd();
166
hash += QT_PREPEND_NAMESPACE(qHash)(it.key()) + QT_PREPEND_NAMESPACE(qHash)(it.value());
172
#ifndef QT_NO_DEBUG_STREAM
173
QDebug operator<<(QDebug dbg, const QVersitProperty& property)
175
QStringList groups = property.groups();
176
QString name = property.name();
177
QMultiHash<QString,QString> parameters = property.parameters();
178
dbg.nospace() << "QVersitProperty(";
179
foreach (const QString& group, groups) {
180
dbg.nospace() << group << '.';
182
dbg.nospace() << name;
183
QHash<QString,QString>::const_iterator it;
184
for (it = parameters.constBegin(); it != parameters.constEnd(); ++it) {
185
dbg.nospace() << ';' << it.key() << '=' << it.value();
187
if (property.valueType() == QVersitProperty::VersitDocumentType)
188
dbg.nospace() << ':' << property.value<QVersitDocument>();
190
dbg.nospace() << ':' << property.variantValue();
191
dbg.nospace() << ')';
192
return dbg.maybeSpace();
197
* Sets the groups in the property to the given list of \a groups.
199
void QVersitProperty::setGroups(const QStringList& groups)
202
foreach (const QString& group, groups) {
203
d->mGroups.append(group);
208
* Gets the groups of the property.
210
QStringList QVersitProperty::groups() const
216
* Sets the \a name of the property.
217
* The \a name is converted to upper-case.
219
void QVersitProperty::setName(const QString& name)
221
d->mName = name.toUpper();
225
* Gets the name of the property in upper-case.
227
QString QVersitProperty::name() const
233
* Replaces all the parameters with \a parameters.
234
* The names of the parameters are converted to upper-case.
236
void QVersitProperty::setParameters(const QMultiHash<QString,QString>& parameters)
238
d->mParameters.clear();
239
// Traverse parameters in the reverse order, because they are added to
240
// d->mParameters using insert in QVersitProperty::addParameter
241
QList<QString> keys = parameters.uniqueKeys();
242
for (int i=keys.count()-1; i >= 0; i--) {
243
QString key = keys.at(i);
244
QList<QString> values = parameters.values(key);
245
for (int j=values.count()-1; j >= 0; j--) {
246
// Convert all the parameter names and values to upper case
247
insertParameter(key,values.at(j));
253
* Adds a new parameter with \a name and \a value.
254
* The parameter name is converted to upper-case.
256
void QVersitProperty::insertParameter(const QString& name, const QString& value)
258
d->mParameters.insert(name.toUpper(), value);
262
* Removes a parameter with \a name and \a value.
264
* \sa removeParameters()
266
void QVersitProperty::removeParameter(const QString& name, const QString& value)
268
d->mParameters.remove(name.toUpper(), value);
272
* Removes all parameters with the given \a name.
274
* \sa removeParameter()
276
void QVersitProperty::removeParameters(const QString& name)
278
d->mParameters.remove(name.toUpper());
282
* Return a copy of the contained list of parameters.
283
* Note that actual the parameters cannot be modified using the copy.
285
QMultiHash<QString,QString> QVersitProperty::parameters() const
287
return d->mParameters;
291
* Sets the property value to \a value.
293
void QVersitProperty::setValue(const QVariant& value)
299
* Returns the value of the property.
301
QVariant QVersitProperty::variantValue() const
307
* \fn T QVersitProperty::value() const
309
* Returns the value of the property as a \tt T.
313
* Returns the value of the property as a string if possible, otherwise return an empty string.
314
* If the property is stored as a QByteArray, it is decoded using the charset specified in the
315
* property's parameters.
316
* \sa QVariant::toString()
318
QString QVersitProperty::value() const
320
if (d->mValue.type() == QVariant::ByteArray) {
321
if (d->mParameters.contains(QStringLiteral("CHARSET"))) {
322
QTextCodec* codec = QTextCodec::codecForName(
323
d->mParameters.value(QStringLiteral("CHARSET")).toLatin1());
325
return codec->toUnicode(d->mValue.toByteArray());
330
return d->mValue.toString();
335
* Sets the type of value held in the property to \a type.
337
void QVersitProperty::setValueType(QVersitProperty::ValueType type)
339
d->mValueType = type;
343
* Returns the type of value held in the property.
345
QVersitProperty::ValueType QVersitProperty::valueType() const
347
return d->mValueType;
351
* Returns true if the property is empty.
353
bool QVersitProperty::isEmpty() const
355
return d->mGroups.isEmpty()
356
&& d->mName.isEmpty()
357
&& d->mParameters.isEmpty()
358
&& !d->mValue.isValid();
362
* Clears the contents of this property.
364
void QVersitProperty::clear()
369
d->mParameters.clear();
370
d->mValueType = QVersitProperty::PlainType;
373
QT_END_NAMESPACE_VERSIT