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 "qversitdocument.h"
35#include "qversitdocument_p.h"
36
37#ifndef QT_NO_DEBUG_STREAM
38#include <QtCore/qdebug.h>
39#endif
40
41QT_BEGIN_NAMESPACE_VERSIT
42
43/*!
44 \class QVersitDocument
45 \brief The QVersitDocument class is a container for a list of versit properties.
46 \ingroup versit
47 \inmodule QtVersit
48
49 A vCard is represented in abstract form as a QVersitDocument that consists of a number of
50 properties such as a name (N), a telephone number (TEL) and an email address (EMAIL), for
51 instance. Each of these properties is stored as an instance of a QVersitProperty in a
52 QVersitDocument.
53
54 In addition to the list of properties, QVersitDocument also records the type of the Versit
55 document in two ways. The VersitType enum describes the format in which the document is to be
56 serialized by QVersitWriter (or the format from which it was read by QVersitReader), and should
57 not be used to infer any semantics about the document data. The componentType field is a string
58 corresponding directly to the value of the BEGIN line in a document. For example, for a vCard,
59 this will always be the string "VCARD"; for an iCalendar, it could be "VCALENDAR", "VEVENT",
60 "VTODO", "VJOURNAL", "VALARM" or "VTIMEZONE".
61
62 As well as properties, a QVersitDocument can hold other documents. For iCalendar, this is how
63 a single VCALENDAR document can compose documents of type VEVENT, VTODO, etc.
64
65 For example, for the following iCalendar:
66 \code
67 BEGIN:VCALENDAR
68 VERSION:2.0
69 BEGIN:VEVENT
70 SUMMARY:Christmas
71 DTSTART:20001225
72 END:VEVENT
73 END:VCALENDAR
74 \endcode
75
76 This can be represented as a QVersitDocument of with componentType VCALENDAR and versitType
77 ICalendar20Type. It contains no properties (note: the VERSION property is not stored explicitly
78 as a property) and one sub-document. The sub-document has componentType VEVENT and versitType
79 ICalendar20Type, and contains two properties.
80
81 QVersitDocument supports implicit sharing.
82
83 \sa QVersitProperty
84 */
85
86/*!
87 \enum QVersitDocument::VersitType
88 This enum describes a Versit document serialization format and version.
89 \value InvalidType No type specified or a document with an invalid type was parsed
90 \value VCard21Type vCard version 2.1
91 \value VCard30Type vCard version 3.0
92 \value VCard40Type vCard version 4.0
93 \value ICalendar20Type iCalendar version 2.0
94 */
95
96/*! Constructs a new empty document */
97QVersitDocument::QVersitDocument() : d(new QVersitDocumentPrivate())
98{
99}
100
101/*! Constructs a new empty document with the type set to \a type */
102QVersitDocument::QVersitDocument(VersitType type) : d(new QVersitDocumentPrivate())
103{
104 d->mVersitType = type;
105}
106
107
108/*! Constructs a document that is a copy of \a other */
109QVersitDocument::QVersitDocument(const QVersitDocument& other) : d(other.d)
110{
111}
112
113/*! Frees the memory used by the document */
114QVersitDocument::~QVersitDocument()
115{
116}
117
118/*! Assigns this document to \a other */
119QVersitDocument& QVersitDocument::operator=(const QVersitDocument& other)
120{
121 if (this != &other)
122 d = other.d;
123 return *this;
124}
125
126/*! Returns true if this is equal to \a other; false otherwise. */
127bool QVersitDocument::operator==(const QVersitDocument& other) const
128{
129 return d->mVersitType == other.d->mVersitType &&
130 d->mProperties == other.d->mProperties &&
131 d->mSubDocuments == other.d->mSubDocuments &&
132 d->mComponentType == other.d->mComponentType;
133}
134
135/*! Returns true if this is not equal to \a other; false otherwise. */
136bool QVersitDocument::operator!=(const QVersitDocument& other) const
137{
138 return !(*this == other);
139}
140
141/*! Returns the hash value for \a key. */
142uint qHash(const QVersitDocument &key)
143{
144 int hash = QT_PREPEND_NAMESPACE(qHash)(key: key.type());
145 hash += QT_PREPEND_NAMESPACE(qHash)(key: key.componentType());
146 hash += key.properties().length() + key.subDocuments().length();
147 foreach (const QVersitProperty& property, key.properties()) {
148 hash += qHash(key: property);
149 }
150 foreach (const QVersitDocument& nested, key.subDocuments()) {
151 hash += qHash(key: nested);
152 }
153 return hash;
154}
155
156#ifndef QT_NO_DEBUG_STREAM
157QDebug operator<<(QDebug dbg, const QVersitDocument& document)
158{
159 dbg.nospace() << "QVersitDocument(" << document.type() << ", " << document.componentType() << ')';
160 foreach (const QVersitProperty& property, document.properties()) {
161 dbg.space() << '\n' << property;
162 }
163 foreach (const QVersitDocument& nested, document.subDocuments()) {
164 dbg.space() << '\n' << nested;
165 }
166 return dbg.maybeSpace();
167}
168#endif
169
170/*!
171 * Sets the versit document type to \a type. This determines the format in which the document is
172 * to be serialized.
173 */
174void QVersitDocument::setType(VersitType type)
175{
176 d->mVersitType = type;
177}
178
179/*!
180 * Gets the versit document type.
181 */
182QVersitDocument::VersitType QVersitDocument::type() const
183{
184 return d->mVersitType;
185}
186
187/*!
188 * Sets the versit component type to \a componentType (eg. VCARD, VCALENDAR, VEVENT, etc.)
189 */
190void QVersitDocument::setComponentType(QString componentType)
191{
192 d->mComponentType = componentType;
193}
194
195/*!
196 * Gets the versit component type
197 */
198QString QVersitDocument::componentType() const
199{
200 return d->mComponentType;
201}
202
203/*!
204 * Add \a property to the list of contained versit properties.
205 * The property is appended as the last property of the list.
206 */
207void QVersitDocument::addProperty(const QVersitProperty& property)
208{
209 d->mProperties.append(t: property);
210}
211
212/*!
213 * Removes the property \a property from the versit document.
214 */
215void QVersitDocument::removeProperty(const QVersitProperty& property)
216{
217 d->mProperties.removeAll(t: property);
218}
219
220/*!
221 * Removes all the properties with the given \a name from the versit document.
222 */
223void QVersitDocument::removeProperties(const QString& name)
224{
225 for (int i=d->mProperties.count()-1; i >=0; i--) {
226 if (d->mProperties[i].name() == name) {
227 d->mProperties.removeAt(i);
228 }
229 }
230}
231
232/*!
233 * Sets the list of properties to \a properties. Logically, all of the existing properties are
234 * removed and all of the supplied \a properties are added.
235 */
236void QVersitDocument::setProperties(const QList<QVersitProperty>& properties)
237{
238 d->mProperties = properties;
239}
240
241/*!
242 * Gets the list of the contained versit properties.
243 * Note that the actual properties cannot be modified using the copy.
244 */
245QList<QVersitProperty> QVersitDocument::properties() const
246{
247 return d->mProperties;
248}
249
250/*!
251 * Adds \a subdocument to the Versit document.
252 */
253void QVersitDocument::addSubDocument(const QVersitDocument& subdocument)
254{
255 d->mSubDocuments.append(t: subdocument);
256}
257
258/*!
259 * Removes the \a subdocument from the versit document.
260 */
261void QVersitDocument::removeSubDocument(const QVersitDocument& subdocument)
262{
263 d->mSubDocuments.removeAll(t: subdocument);
264}
265
266/*!
267 * Sets the list of subdocuments to \a documents.
268 */
269void QVersitDocument::setSubDocuments(const QList<QVersitDocument>& documents)
270{
271 d->mSubDocuments = documents;
272}
273
274/*!
275 * Returns the list of subdocuments contained within this Versit document.
276 */
277QList<QVersitDocument> QVersitDocument::subDocuments() const
278{
279 return d->mSubDocuments;
280}
281
282/*!
283 * Returns true if the document is empty.
284 */
285bool QVersitDocument::isEmpty() const
286{
287 return d->mProperties.isEmpty()
288 && d->mSubDocuments.isEmpty()
289 && d->mVersitType == QVersitDocument::InvalidType;
290}
291
292/*!
293 * Clears the document, removing all properties, sub-documents and metadata.
294 */
295void QVersitDocument::clear()
296{
297 d->mProperties.clear();
298 d->mSubDocuments.clear();
299 d->mVersitType = QVersitDocument::InvalidType;
300 d->mComponentType.clear();
301}
302
303QT_END_NAMESPACE_VERSIT
304

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