--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/versit/qversitproperty.cpp Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** 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 "qversitproperty.h"
+#include "qversitproperty_p.h"
+#include "qmobilityglobal.h"
+
+#include <QStringList>
+#include <QTextCodec>
+
+QTM_BEGIN_NAMESPACE
+
+/*!
+ \class QVersitProperty
+ \brief The QVersitProperty class stores the name, value, groups and parameters of a Versit property.
+ \ingroup versit
+
+ A vCard is represented in abstract form as a QVersitDocument that consists of a number of
+ properties such as a name (N), a telephone number (TEL) and an email address (EMAIL), for
+ instance. Each of these properties is stored as an instance of a QVersitProperty in a
+ QVersitDocument.
+
+ A QVersitProperty consists of a list of groups, a name, a list of parameters (key/value pairs),
+ and a value.
+
+ The value of a QVersitProperty is stored as a QVariant and should always be one of four types:
+ QString for textual values, QByteArray for binary data (eg. images), QStringList for structured
+ textual data, or QVersitDocument for nested documents. The \l QVersitReader will parse Versit
+ properties and assign the correct type of object to the property value. The \l QVersitWriter will
+ serialize objects of these types correctly into the (text-based) Versit format.
+
+ For example, a property might appear in a vCard as:
+ \code
+ ADR;TYPE=home,postal:;;123 Main Street;Any Town;CA;91921-1234
+ \endcode
+ This would be stored as a QVersitProperty with the name \tt{ADR} and two parameters (both named
+ \tt{TYPE} and with values \tt{home} and \tt{postal} respectively. The value of the
+ QVersitProperty is a QStringList with six strings, and the valueType is CompoundType.
+
+ QVersitProperty supports implicit sharing. The property name and parameter names of a
+ QVersitProperty are converted to upper-case when they are stored to a QVersitProperty.
+
+ \sa QVersitDocument
+ */
+
+/*!
+ \enum QVersitProperty::ValueType
+ Describes the type of data held in the property's value.
+
+ The vCard and iCalendar specifications allows a property value to hold a string, binary data, or a
+ nested document. String values can either be unstructured or structured. Structured strings can
+ be either of compound type or list type. A compound value is one that is delimited by semicolons,
+ allows empty components, and has a property-specific cardinality and ordering. A list value is
+ one that is delimited by commas, does not have empty components, and has no restrictions on
+ cardinality or ordering.
+
+ \value PlainType The property value holds an unstructured string and can be retrieved with
+ QVersitProperty::value()
+ \value CompoundType The property value holds a compound string and can be retrieved with
+ QVersitProperty::value<QStringList>()
+ \value ListType The property value holds a list of strings and can be retrieved with
+ QVersitProperty::value<QStringList>()
+ \value BinaryType The property value holds a binary value and can be retrieved with
+ QVersitProperty::value<QByteArray>()
+ \value VersitDocumentType The property value holds a nested Versit document and can be retrieved
+ with QVersitProperty::value<QVersitDocument>()
+ */
+
+/*! Constructs a new empty property */
+QVersitProperty::QVersitProperty() : d(new QVersitPropertyPrivate())
+{
+}
+
+/*! Constructs a property that is a copy of \a other */
+QVersitProperty::QVersitProperty(const QVersitProperty& other) : d(other.d)
+{
+}
+
+/*! Frees the memory used by the property */
+QVersitProperty::~QVersitProperty()
+{
+}
+
+/*! Assigns this property to \a other */
+QVersitProperty& QVersitProperty::operator=(const QVersitProperty& other)
+{
+ if (this != &other)
+ d = other.d;
+ return *this;
+}
+
+/*! Returns true if this is equal to \a other; false otherwise. */
+bool QVersitProperty::operator==(const QVersitProperty& other) const
+{
+ bool equal = d->mGroups == other.d->mGroups &&
+ d->mName == other.d->mName &&
+ d->mParameters == other.d->mParameters &&
+ d->mValueType == other.d->mValueType;
+ if (!equal)
+ return false;
+
+ // QVariant doesn't support == on QVersitDocuments - do it manually
+ if (d->mValue.userType() == qMetaTypeId<QVersitDocument>())
+ return other.d->mValue.userType() == qMetaTypeId<QVersitDocument>()
+ && d->mValue.value<QVersitDocument>() == other.d->mValue.value<QVersitDocument>();
+ else
+ return d->mValue == other.d->mValue;
+}
+
+/*! Returns true if this is not equal to \a other; false otherwise. */
+bool QVersitProperty::operator!=(const QVersitProperty& other) const
+{
+ return !(*this == other);
+}
+
+/*! Returns the hash value for \a key. */
+uint qHash(const QVersitProperty &key)
+{
+ uint hash = QT_PREPEND_NAMESPACE(qHash)(key.name()) + QT_PREPEND_NAMESPACE(qHash)(key.value());
+ foreach (const QString& group, key.groups()) {
+ hash += QT_PREPEND_NAMESPACE(qHash)(group);
+ }
+ QHash<QString,QString>::const_iterator it = key.parameters().constBegin();
+ QHash<QString,QString>::const_iterator end = key.parameters().constEnd();
+ while (it != end) {
+ hash += QT_PREPEND_NAMESPACE(qHash)(it.key()) + QT_PREPEND_NAMESPACE(qHash)(it.value());
+ ++it;
+ }
+ return hash;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QVersitProperty& property)
+{
+ QStringList groups = property.groups();
+ QString name = property.name();
+ QMultiHash<QString,QString> parameters = property.parameters();
+ dbg.nospace() << "QVersitProperty(";
+ foreach (const QString& group, groups) {
+ dbg.nospace() << group << '.';
+ }
+ dbg.nospace() << name;
+ QHash<QString,QString>::const_iterator it;
+ for (it = parameters.constBegin(); it != parameters.constEnd(); ++it) {
+ dbg.nospace() << ';' << it.key() << '=' << it.value();
+ }
+ dbg.nospace() << ':' << property.variantValue();
+ dbg.nospace() << ')';
+ return dbg.maybeSpace();
+}
+#endif
+
+/*!
+ * Sets the groups in the property to the given list of \a groups.
+ */
+void QVersitProperty::setGroups(const QStringList& groups)
+{
+ d->mGroups.clear();
+ foreach (const QString& group, groups) {
+ d->mGroups.append(group);
+ }
+}
+
+/*!
+ * Gets the groups of the property.
+ */
+QStringList QVersitProperty::groups() const
+{
+ return d->mGroups;
+}
+
+/*!
+ * Sets the \a name of the property.
+ * The \a name is converted to upper-case.
+ */
+void QVersitProperty::setName(const QString& name)
+{
+ d->mName = name.toUpper();
+}
+
+/*!
+ * Gets the name of the property in upper-case.
+ */
+QString QVersitProperty::name() const
+{
+ return d->mName;
+}
+
+/*!
+ * Replaces all the parameters with \a parameters.
+ * The parameters are converted to upper-case.
+ */
+void QVersitProperty::setParameters(const QMultiHash<QString,QString>& parameters)
+{
+ d->mParameters.clear();
+ // Traverse parameters in the reverse order, because they are added to
+ // d->mParameters using insert in QVersitProperty::addParameter
+ QList<QString> keys = parameters.uniqueKeys();
+ for (int i=keys.count()-1; i >= 0; i--) {
+ QString key = keys.at(i);
+ QList<QString> values = parameters.values(key);
+ for (int j=values.count()-1; j >= 0; j--) {
+ // Convert all the parameter names and values to upper case
+ insertParameter(key,values.at(j));
+ }
+ }
+}
+
+/*!
+ * Adds a new parameter with \a name and \a value.
+ * Both the name and the value are converted to upper-case.
+ */
+void QVersitProperty::insertParameter(const QString& name, const QString& value)
+{
+ d->mParameters.insert(name.toUpper(), value);
+}
+
+/*!
+ * Removes a parameter with \a name and \a value.
+ *
+ * \sa removeParameters()
+ */
+void QVersitProperty::removeParameter(const QString& name, const QString& value)
+{
+ d->mParameters.remove(name.toUpper(), value);
+}
+
+/*!
+ * Removes all parameters with the given \a name.
+ *
+ * \sa removeParameter()
+ */
+void QVersitProperty::removeParameters(const QString& name)
+{
+ d->mParameters.remove(name.toUpper());
+}
+
+/*!
+ * Return a copy of the contained list of parameters.
+ * Note that actual the parameters cannot be modified using the copy.
+ */
+QMultiHash<QString,QString> QVersitProperty::parameters() const
+{
+ return d->mParameters;
+}
+
+/*!
+ * Sets the property value to \a value.
+ */
+void QVersitProperty::setValue(const QVariant& value)
+{
+ d->mValue = value;
+}
+
+/*!
+ * Returns the value of the property.
+ */
+QVariant QVersitProperty::variantValue() const
+{
+ return d->mValue;
+}
+
+/*!
+ * \fn T QVersitProperty::value() const
+ * \overload
+ * Returns the value of the property as a \tt T.
+ */
+
+/*!
+ * Returns the value of the property as a string if possible, otherwise return an empty string.
+ * If the property is stored as a QByteArray, it is decoded using the charset specified in the
+ * property's parameters.
+ * \sa QVariant::toString()
+ */
+QString QVersitProperty::value() const
+{
+ if (d->mValue.type() == QVariant::ByteArray) {
+ if (d->mParameters.contains(QLatin1String("CHARSET"))) {
+ QTextCodec* codec = QTextCodec::codecForName(
+ d->mParameters.value(QLatin1String("CHARSET")).toAscii());
+ if (codec != NULL) {
+ return codec->toUnicode(d->mValue.toByteArray());
+ }
+ }
+ return QString();
+ } else {
+ return d->mValue.toString();
+ }
+}
+
+/*!
+ * Sets the type of value held in the property to \a type.
+ */
+void QVersitProperty::setValueType(QVersitProperty::ValueType type)
+{
+ d->mValueType = type;
+}
+
+/*!
+ * Returns the type of value held in the property.
+ */
+QVersitProperty::ValueType QVersitProperty::valueType() const
+{
+ return d->mValueType;
+}
+
+/*!
+ * Returns true if the property is empty.
+ */
+bool QVersitProperty::isEmpty() const
+{
+ return d->mGroups.isEmpty()
+ && d->mName.isEmpty()
+ && d->mParameters.isEmpty()
+ && !d->mValue.isValid();
+}
+
+/*!
+ * Clears the contents of this property.
+ */
+void QVersitProperty::clear()
+{
+ d->mGroups.clear();
+ d->mName.clear();
+ d->mValue.clear();
+ d->mParameters.clear();
+}
+
+QTM_END_NAMESPACE