~chris.gagnon/+junk/qtpim-coverage

« back to all changes in this revision

Viewing changes to src/organizer/qorganizeritem.cpp

  • Committer: chris.gagnon
  • Date: 2013-12-10 23:09:37 UTC
  • Revision ID: chris.gagnon@canonical.com-20131210230937-2akf1ft1edcttk87
first post

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtOrganizer module of the Qt Toolkit.
 
7
**
 
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.
 
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 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.
 
24
**
 
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.
 
28
**
 
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.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include <qorganizeritem.h>
 
43
#include <private/qorganizeritem_p.h>
 
44
#include <private/qorganizeritemdetail_p.h>
 
45
#include <qorganizeritemdetails.h>
 
46
 
 
47
#include <qdebug.h>
 
48
#include <qdatastream.h>
 
49
 
 
50
QT_BEGIN_NAMESPACE_ORGANIZER
 
51
 
 
52
/*!
 
53
    \macro Q_DECLARE_CUSTOM_ORGANIZER_ITEM
 
54
    \relates QOrganizerItem
 
55
 
 
56
    Macro for simplifying declaring convenience leaf classes for QOrganizerItem.
 
57
 
 
58
    The first argument is the name of the class, and the second argument is the
 
59
    item type.
 
60
 */
 
61
 
 
62
/*!
 
63
    \class QOrganizerItem
 
64
    \brief The QOrganizerItem class is the base class of an event, todo, note, or journal entry.
 
65
    \inmodule QtOrganizer
 
66
    \ingroup organizer-main
 
67
 
 
68
    A QOrganizerItem object has an id and a collection of details (like a start date and location), as
 
69
    well as a collection id which identifies which QOrganizerCollection the item is part of in a manager.
 
70
    Each detail (which can have multiple fields) is stored in an appropriate subclass of QOrganizerItemDetail,
 
71
    and the QOrganizerItem allows retrieving these details in various ways. QOrganizerItemExtendedDetail is
 
72
    supposed to be used to store user specific details that are not pre-defined in the detal leaf classes.
 
73
 
 
74
    Most clients will want to use the convenient subclasses of QOrganizerItem (i.e., QOrganizerEvent
 
75
    (and QOrganizerEventOccurence), QOrganizerTodo (and QOrganizerTodoOccurence), QOrganizerJournal and
 
76
    QOrganizerNote) instead of manipulating instances of QOrganizerItem directly.
 
77
 
 
78
    A QOrganizerItem instance represents the in-memory version of an organizer item.
 
79
    It is possible for the contents of a QOrganizerItem to change independently of the contents
 
80
    that are stored persistently in a QOrganizerManager.  A QOrganizerItem has an id associated
 
81
    with it when it is first retrieved from a QOrganizerManager, or after it has been first saved,
 
82
    and this allows clients to track changes using the signals in QOrganizerManager.  When saved
 
83
    in a manager, every item is placed into a QOrganizerCollection in that manager, according
 
84
    to the collection id set in the item prior to save (or the default collection if no
 
85
    collection id was set in the item).
 
86
 
 
87
    Different QOrganizerManagers may require an item to have certain details saved in it before
 
88
    it can be stored in that manager.  By default, every item must have a QOrganizerItemType
 
89
    detail which identifies the type of the item.  Different subclasses of QOrganizerItem
 
90
    (i.e., QOrganizerEvent (and QOrganizerEventOccurence), QOrganizerTodo (and QOrganizerTodoOccurence),
 
91
    QOrganizerJournal and QOrganizerNote) may have other mandatory details, depending on the manager.
 
92
 
 
93
    \sa QOrganizerManager, QOrganizerItemDetail
 
94
 */
 
95
 
 
96
/*!
 
97
    \fn QOrganizerItem::operator!=(const QOrganizerItem &other) const
 
98
 
 
99
    Returns true if this organizer item's id or details are different to those of the \a other organizer item.
 
100
 */
 
101
 
 
102
/*!
 
103
    Construct an empty organizer item.
 
104
 
 
105
    The organizer item will have an empty item ID, and an empty collection ID. It's of type \l QOrganizerItemType::TypeUndefined.
 
106
 */
 
107
QOrganizerItem::QOrganizerItem()
 
108
    : d(new QOrganizerItemData)
 
109
{
 
110
    QOrganizerItemType organizeritemType;
 
111
    organizeritemType.setType(QOrganizerItemType::TypeUndefined);
 
112
    d->m_details.append(organizeritemType);
 
113
}
 
114
 
 
115
/*!
 
116
    Constructs an item that is a copy of \a other.
 
117
 */
 
118
QOrganizerItem::QOrganizerItem(const QOrganizerItem &other)
 
119
    : d(other.d)
 
120
{
 
121
}
 
122
 
 
123
/*!
 
124
    \internal
 
125
 
 
126
    Constructs a new, empty item of the given type \a type.
 
127
*/
 
128
QOrganizerItem::QOrganizerItem(QOrganizerItemType::ItemType type)
 
129
    : d(new QOrganizerItemData)
 
130
{
 
131
    QOrganizerItemType organizeritemType;
 
132
    organizeritemType.setType(type);
 
133
    d->m_details.append(organizeritemType);
 
134
}
 
135
 
 
136
/*!
 
137
    \internal
 
138
 
 
139
    Constructs an item that is a copy of \a other if \a other is of the expected type
 
140
    identified by \a expectedType, else constructs a new, empty item of the
 
141
    type identified by the \a expectedType.
 
142
 
 
143
    The \a expectedType pointer must be valid for the lifetime of the program.
 
144
*/
 
145
QOrganizerItem::QOrganizerItem(const QOrganizerItem &other, QOrganizerItemType::ItemType expectedType)
 
146
{
 
147
    if (other.type() == expectedType) {
 
148
        d = other.d;
 
149
    } else {
 
150
        d = new QOrganizerItemData;
 
151
        setType(expectedType);
 
152
    }
 
153
}
 
154
 
 
155
/*!
 
156
    \internal
 
157
 
 
158
    Assigns this item to \a other if the type of \a other is that identified
 
159
    by the given \a expectedType, else assigns this item to be a new, empty
 
160
    item of the type identified by the given \a expectedType
 
161
*/
 
162
QOrganizerItem &QOrganizerItem::assign(const QOrganizerItem &other, QOrganizerItemType::ItemType expectedType)
 
163
{
 
164
    if (this != &other) {
 
165
        if (other.type() == expectedType) {
 
166
            d = other.d;
 
167
        } else {
 
168
            d = new QOrganizerItemData;
 
169
            setType(expectedType);
 
170
        }
 
171
    }
 
172
    return *this;
 
173
}
 
174
 
 
175
 
 
176
/*!
 
177
    Returns true if this QOrganizerItem is empty, false if not.
 
178
 
 
179
    Note that the type detail of the organizer item is irrelevant.
 
180
 */
 
181
bool QOrganizerItem::isEmpty() const
 
182
{
 
183
    return (d->m_details.count() == 1);
 
184
}
 
185
 
 
186
/*!
 
187
    Removes all details of the organizer item, and resets the type to be \l QOrganizerItemType::TypeUndefined.
 
188
 */
 
189
void QOrganizerItem::clearDetails()
 
190
{
 
191
    d->m_details.clear();
 
192
 
 
193
    QOrganizerItemType organizeritemType;
 
194
    organizeritemType.setType(QOrganizerItemType::TypeUndefined);
 
195
    d->m_details.append(organizeritemType);
 
196
}
 
197
 
 
198
/*!
 
199
    Replace the contents of this organizer item with the \a other.
 
200
 */
 
201
QOrganizerItem &QOrganizerItem::operator=(const QOrganizerItem &other)
 
202
{
 
203
    d = other.d;
 
204
    return *this;
 
205
}
 
206
 
 
207
/*!
 
208
    Frees the memory used by this item.
 
209
 */
 
210
QOrganizerItem::~QOrganizerItem()
 
211
{
 
212
}
 
213
 
 
214
/*!
 
215
    Returns the QOrganizerItemId that identifies this organizer item.
 
216
 
 
217
    This may have been set when the organizer item was retrieved from
 
218
    a particular manager, or when the organizer item was first saved
 
219
    in a manager.  The QOrganizerItemId is only valid within a specific
 
220
    manager.  See \l QOrganizerManager::saveItem() for more
 
221
    information.
 
222
 */
 
223
QOrganizerItemId QOrganizerItem::id() const
 
224
{
 
225
    return d->m_id;
 
226
}
 
227
 
 
228
/*!
 
229
    Returns the id of the collection which this item is part of, in the manager
 
230
    in which the item has been saved, if the item has previously been saved in
 
231
    a manager.  If the item has not previously been saved in a manager, this function
 
232
    will return the id of the collection into which the client wishes the item to be
 
233
    saved when \l QOrganizerManager::saveItem() is called, which is set by calling
 
234
    \l setId(); otherwise, returns a null id.
 
235
 
 
236
    An item always belongs to exactly one collection in a particular manager after it
 
237
    has been saved in the manager.  If the item has previously been saved in the manager,
 
238
    in a particular collection, and the client sets the collection id of the item to
 
239
    the id of a different collection within that manager and then resaves the item,
 
240
    the item will be moved from its original collection into the specified collection
 
241
    if the move operation is supported by the manager; otherwise, the
 
242
    \l QOrganizerManager::saveItem() operation will fail and calling
 
243
    \l QOrganizerManager::error() will return \c QOrganizerManager::NotSupportedError.
 
244
 */
 
245
QOrganizerCollectionId QOrganizerItem::collectionId() const
 
246
{
 
247
    return d->m_collectionId;
 
248
}
 
249
 
 
250
/*!
 
251
    Sets the id of the collection into which the client wishes the item to be saved
 
252
    to the given \a collectionId.
 
253
 
 
254
    If the given \a collectionId is the null collection id, the client is specifying
 
255
    that the item should be saved into the collection in which the item is already
 
256
    saved (if the item has previously been saved in the manager, without having been
 
257
    removed since), or into the default collection of the manager (if the item has
 
258
    not previously been saved in the manager, or has been removed since the last time
 
259
    it was saved).
 
260
 
 
261
    If the item has previously been saved in a particular manager, and the given
 
262
    \a collectionId is the id of a different collection than the one which the
 
263
    item is currently a part of in that manager, saving the item with
 
264
    \l QOrganizerManager::saveItem() will move the item from its original
 
265
    collection to the collection whose id is \a collectionId, if \a collectionId
 
266
    identifies a valid collection and the operation is supported by the manager.
 
267
 */
 
268
void QOrganizerItem::setCollectionId(const QOrganizerCollectionId &collectionId)
 
269
{
 
270
    d->m_collectionId = collectionId;
 
271
}
 
272
 
 
273
/*!
 
274
    Sets the id of this organizer item to \a id.
 
275
 
 
276
    Note that this only affects this object, not any corresponding structures stored
 
277
    by a QOrganizerManager.
 
278
 
 
279
    If you change the id of a organizer item and save the organizer item
 
280
    in a manager, the previously existing organizer item will still
 
281
    exist.  You can do this to create copies (possibly modified)
 
282
    of an existing organizer item, or to save a organizer item in a different manager.
 
283
 
 
284
    \sa QOrganizerManager::saveItem()
 
285
 */
 
286
void QOrganizerItem::setId(const QOrganizerItemId &id)
 
287
{
 
288
    d->m_id = id;
 
289
    // TODO - reset collection id?
 
290
}
 
291
 
 
292
/*!
 
293
    Returns the first detail stored in the organizer item with the given \a detailType. If the
 
294
    given \a detailType is TypeUndefined, it returns the first detail found.
 
295
 */
 
296
QOrganizerItemDetail QOrganizerItem::detail(QOrganizerItemDetail::DetailType detailType) const
 
297
{
 
298
    if (detailType == QOrganizerItemDetail::TypeUndefined)
 
299
        return d->m_details.first();
 
300
 
 
301
    for (int i = 0; i < d->m_details.size(); i++) {
 
302
        const QOrganizerItemDetail &existing = d->m_details.at(i);
 
303
        if (existing.d->m_detailType == detailType)
 
304
            return existing;
 
305
    }
 
306
 
 
307
    return QOrganizerItemDetail();
 
308
}
 
309
 
 
310
/*!
 
311
    Returns a list of details with the given \a detailType. If the given \a detailType is of TypeUndefined,
 
312
    it returns all the details.
 
313
 */
 
314
QList<QOrganizerItemDetail> QOrganizerItem::details(QOrganizerItemDetail::DetailType detailType) const
 
315
{
 
316
    if (detailType == QOrganizerItemDetail::TypeUndefined)
 
317
        return d->m_details;
 
318
 
 
319
    QList<QOrganizerItemDetail> sublist;
 
320
    for (int i = 0; i < d->m_details.size(); i++) {
 
321
        const QOrganizerItemDetail &existing = d->m_details.at(i);
 
322
        if (existing.d->m_detailType == detailType)
 
323
            sublist.append(existing);
 
324
    }
 
325
    return sublist;
 
326
}
 
327
 
 
328
/*!
 
329
    Saves the given \a detail in the list of stored details, and sets the detail's id.
 
330
    If another detail of the same type and id has been previously saved in
 
331
    this organizer item, that detail is overwritten.  Otherwise, a new id is generated
 
332
    and set in the detail, and the detail is added to the organizer item.
 
333
 
 
334
    If \a detail is a QOrganizerItemType, the existing organizer item type will
 
335
    be overwritten with \a detail.  There is never more than one organizer item type
 
336
    in a organizer item.
 
337
 
 
338
    Returns true if the detail was saved successfully, otherwise returns false.
 
339
 
 
340
    Note that the caller retains ownership of the detail.
 
341
 */
 
342
bool QOrganizerItem::saveDetail(QOrganizerItemDetail *detail)
 
343
{
 
344
    if (!detail)
 
345
        return false;
 
346
 
 
347
    // we only allow one instance of these details per item
 
348
    if (detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeItemType
 
349
        || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeDescription
 
350
        || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeDisplayLabel
 
351
        || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeClassification
 
352
        || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeVersion) {
 
353
        for (int i = 0; i < d.constData()->m_details.size(); i++) {
 
354
            if (detail->d.constData()->m_detailType == d.constData()->m_details.at(i).d.constData()->m_detailType) {
 
355
                d->m_details.replace(i, *detail);
 
356
                return true;
 
357
            }
 
358
        }
 
359
        // doesn't already exist; append it.
 
360
        d->m_details.append(*detail);
 
361
        return true;
 
362
    }
 
363
 
 
364
    // try to find the "old version" of this field
 
365
    // ie, the one with the same type and id, but different value or attributes.
 
366
    for (int i = 0; i < d.constData()->m_details.size(); i++) {
 
367
        const QOrganizerItemDetail& curr = d.constData()->m_details.at(i);
 
368
        if (detail->d.constData()->m_detailType == curr.d.constData()->m_detailType && detail->d.constData()->m_id == curr.d.constData()->m_id) {
 
369
            // update the detail constraints of the supplied detail
 
370
            // Found the old version.  Replace it with this one.
 
371
            d->m_details[i] = *detail;
 
372
            return true;
 
373
        }
 
374
    }
 
375
    // this is a new detail!  add it to the organizer item.
 
376
    d->m_details.append(*detail);
 
377
    return true;
 
378
}
 
379
 
 
380
/*!
 
381
    Removes the \a detail from the organizer item.
 
382
 
 
383
    The detail in the organizer item which has the same key as that of the given \a detail
 
384
    will be removed if it exists.  Only the key is used for comparison - that is, the
 
385
    information in the detail may be different.
 
386
 
 
387
    Returns true if the detail was removed successfully, false if an error occurred.
 
388
 
 
389
    Note that the caller retains ownership of the detail.
 
390
 */
 
391
bool QOrganizerItem::removeDetail(QOrganizerItemDetail *detail)
 
392
{
 
393
    if (!detail)
 
394
        return false;
 
395
 
 
396
    // find the detail stored in the organizer item which has the same key as the detail argument
 
397
    int removeIndex = -1;
 
398
    for (int i = 0; i < d.constData()->m_details.size(); i++) {
 
399
        if (d.constData()->m_details.at(i).key() == detail->key()) {
 
400
            removeIndex = i;
 
401
            break;
 
402
        }
 
403
    }
 
404
 
 
405
    // make sure the detail exists (in some form) in the organizer item.
 
406
    if (removeIndex < 0)
 
407
        return false;
 
408
 
 
409
    // Type -detail is specific case which cannot be deleted
 
410
    if (QOrganizerItemDetail::TypeItemType == detail->d.constData()->m_detailType)
 
411
        return false;
 
412
 
 
413
    if (!d.constData()->m_details.contains(*detail))
 
414
        return false;
 
415
 
 
416
    // then remove the detail.
 
417
    d->m_details.removeAt(removeIndex);
 
418
    return true;
 
419
}
 
420
 
 
421
/*!
 
422
    Returns true if this organizer item is equal to the \a other organizer item, false if either the
 
423
    id, collection id or stored details are not the same.
 
424
 */
 
425
bool QOrganizerItem::operator==(const QOrganizerItem &other) const
 
426
{
 
427
    if (other.d->m_id != d->m_id
 
428
        || other.d->m_collectionId != d->m_collectionId
 
429
        || d->m_details.size() != other.d->m_details.size()) {
 
430
        return false;
 
431
    }
 
432
 
 
433
    QList<QOrganizerItemDetail> searchList(d->m_details);
 
434
 
 
435
    foreach (const QOrganizerItemDetail &detail, other.d->m_details) {
 
436
        if (!searchList.removeOne(detail))
 
437
            return false;
 
438
    }
 
439
    return true;
 
440
}
 
441
 
 
442
/*!
 
443
    \relates QOrganizerItem
 
444
 
 
445
    Returns the hash value for \a key.
 
446
 */
 
447
uint qHash(const QOrganizerItem &key)
 
448
{
 
449
    uint hash = qHash(key.id());
 
450
    hash += qHash(key.collectionId());
 
451
    foreach (const QOrganizerItemDetail &detail, key.details())
 
452
        hash += qHash(detail);
 
453
    return hash;
 
454
}
 
455
 
 
456
#ifndef QT_NO_DEBUG_STREAM
 
457
/*!
 
458
    \relates QOrganizerItem
 
459
    Streams the \a item to the given debug stream \a dbg, and returns the stream.
 
460
 */
 
461
QDebug operator<<(QDebug dbg, const QOrganizerItem &item)
 
462
{
 
463
    dbg.nospace() << "QOrganizerItem(" << item.id() << ") in collection(" << item.collectionId() << ")";
 
464
    foreach (const QOrganizerItemDetail& detail, item.details())
 
465
        dbg.space() << '\n' << detail;
 
466
    return dbg.maybeSpace();
 
467
}
 
468
#endif // QT_NO_DEBUG_STREAM
 
469
 
 
470
#ifndef QT_NO_DATASTREAM
 
471
/*!
 
472
    \relates QOrganizerItem
 
473
    Writes \a item to the stream \a out.
 
474
 */
 
475
QDataStream &operator<<(QDataStream &out, const QOrganizerItem &item)
 
476
{
 
477
    quint8 formatVersion = 1; // Version of QDataStream format for QOrganizerItem
 
478
    out << formatVersion
 
479
        << item.id().toString()
 
480
        << item.collectionId().toString()
 
481
        << item.details();
 
482
    return out;
 
483
}
 
484
 
 
485
/*!
 
486
    \relates QOrganizerItem
 
487
    Reads an item from stream \a in into \a item.
 
488
 */
 
489
QDataStream &operator>>(QDataStream &in, QOrganizerItem &item)
 
490
{
 
491
    quint8 formatVersion;
 
492
    in >> formatVersion;
 
493
    if (formatVersion == 1) {
 
494
        item = QOrganizerItem();
 
495
        QString itemIdString;
 
496
        QString collectionIdString;
 
497
        QList<QOrganizerItemDetail> details;
 
498
        in >> itemIdString >> collectionIdString >> details;
 
499
        item.setId(QOrganizerItemId::fromString(itemIdString));
 
500
        item.setCollectionId(QOrganizerCollectionId::fromString(collectionIdString));
 
501
        item.d->m_details = details;
 
502
    } else {
 
503
        in.setStatus(QDataStream::ReadCorruptData);
 
504
    }
 
505
    return in;
 
506
}
 
507
#endif // QT_NO_DATASTREAM
 
508
 
 
509
/*!
 
510
    Returns the type of the organizer item.
 
511
 */
 
512
QOrganizerItemType::ItemType QOrganizerItem::type() const
 
513
{
 
514
    // type is always the first detail
 
515
    QOrganizerItemType type = static_cast<QOrganizerItemType>(d->m_details.at(0));
 
516
    return type.type();
 
517
}
 
518
 
 
519
/*!
 
520
    Sets the type of the organizer item to the given \a type.
 
521
 */
 
522
void QOrganizerItem::setType(QOrganizerItemType::ItemType type)
 
523
{
 
524
    if (d->m_details.isEmpty()) {
 
525
        QOrganizerItemType organizeritemType;
 
526
        organizeritemType.setType(type);
 
527
        d->m_details.append(organizeritemType);
 
528
    } else {
 
529
        // type is always the first detail
 
530
        d->m_details.first().setValue(QOrganizerItemType::FieldType, type);
 
531
    }
 
532
}
 
533
 
 
534
/*!
 
535
    Returns the display label of the item.
 
536
 */
 
537
QString QOrganizerItem::displayLabel() const
 
538
{
 
539
    QOrganizerItemDisplayLabel dl = detail(QOrganizerItemDetail::TypeDisplayLabel);
 
540
    return dl.label();
 
541
}
 
542
 
 
543
/*!
 
544
    Sets the display label of the item to \a label.
 
545
 */
 
546
void QOrganizerItem::setDisplayLabel(const QString &label)
 
547
{
 
548
    QOrganizerItemDisplayLabel dl = detail(QOrganizerItemDetail::TypeDisplayLabel);
 
549
    dl.setLabel(label);
 
550
    saveDetail(&dl);
 
551
}
 
552
 
 
553
/*!
 
554
    Returns the human-readable description of the item.
 
555
 */
 
556
QString QOrganizerItem::description() const
 
557
{
 
558
    QOrganizerItemDescription descr = detail(QOrganizerItemDetail::TypeDescription);
 
559
    return descr.description();
 
560
}
 
561
 
 
562
/*!
 
563
    Sets the human-readable description of the item to \a description.
 
564
 */
 
565
void QOrganizerItem::setDescription(const QString &description)
 
566
{
 
567
    QOrganizerItemDescription descr = detail(QOrganizerItemDetail::TypeDescription);
 
568
    descr.setDescription(description);
 
569
    saveDetail(&descr);
 
570
}
 
571
 
 
572
/*!
 
573
    Returns the list of comments of this item.
 
574
 */
 
575
QStringList QOrganizerItem::comments() const
 
576
{
 
577
    QStringList commentList;
 
578
    for (int i = 0; i < d->m_details.size(); ++i) {
 
579
        const QOrganizerItemDetail &detail = d->m_details.at(i);
 
580
        if (detail.d->m_detailType == QOrganizerItemDetail::TypeComment)
 
581
            commentList.append(detail.d->m_values.value(QOrganizerItemComment::FieldComment).toString());
 
582
    }
 
583
    return commentList;
 
584
}
 
585
 
 
586
/*!
 
587
    Removes all comments of this item.
 
588
 */
 
589
void QOrganizerItem::clearComments()
 
590
{
 
591
    d->removeOnly(QOrganizerItemDetail::TypeComment);
 
592
}
 
593
 
 
594
/*!
 
595
    Sets the list of comments associated with the item to \a comments.
 
596
 */
 
597
void QOrganizerItem::setComments(const QStringList &comments)
 
598
{
 
599
    d->removeOnly(QOrganizerItemDetail::TypeComment);
 
600
    foreach (const QString &comment, comments)
 
601
        addComment(comment);
 
602
}
 
603
 
 
604
/*!
 
605
    Adds the \a comment to this item
 
606
 */
 
607
void QOrganizerItem::addComment(const QString &comment)
 
608
{
 
609
    QOrganizerItemComment detail;
 
610
    detail.setComment(comment);
 
611
    saveDetail(&detail);
 
612
}
 
613
 
 
614
/*!
 
615
    Returns the list of tags for this item.
 
616
 */
 
617
QStringList QOrganizerItem::tags() const
 
618
{
 
619
    QStringList tagList;
 
620
    for (int i = 0; i < d->m_details.size(); ++i) {
 
621
        const QOrganizerItemDetail &detail = d->m_details.at(i);
 
622
        if (detail.d->m_detailType == QOrganizerItemDetail::TypeTag)
 
623
            tagList.append(detail.d->m_values.value(QOrganizerItemTag::FieldTag).toString());
 
624
    }
 
625
    return tagList;
 
626
}
 
627
 
 
628
/*!
 
629
    Removes all tags associated with the item.
 
630
 */
 
631
void QOrganizerItem::clearTags()
 
632
{
 
633
    d->removeOnly(QOrganizerItemDetail::TypeTag);
 
634
}
 
635
 
 
636
/*!
 
637
    Adds the \a tag to this item.
 
638
 */
 
639
void QOrganizerItem::addTag(const QString &tag)
 
640
{
 
641
    QOrganizerItemTag tagDetail;
 
642
    tagDetail.setTag(tag);
 
643
    saveDetail(&tagDetail);
 
644
}
 
645
 
 
646
/*!
 
647
    Sets the list of tags associated with the item to \a tags.
 
648
 */
 
649
void QOrganizerItem::setTags(const QStringList &tags)
 
650
{
 
651
    d->removeOnly(QOrganizerItemDetail::TypeTag);
 
652
    foreach (const QString &tag, tags)
 
653
        addTag(tag);
 
654
}
 
655
 
 
656
/*!
 
657
    Returns the globally unique identifier which identifies this item,
 
658
    which is used for synchronization purposes.
 
659
 */
 
660
QString QOrganizerItem::guid() const
 
661
{
 
662
    QOrganizerItemGuid guid = detail(QOrganizerItemDetail::TypeGuid);
 
663
    return guid.guid();
 
664
}
 
665
 
 
666
/*!
 
667
    Sets the item's globally unique identifier to \a guid.
 
668
 */
 
669
void QOrganizerItem::setGuid(const QString &guid)
 
670
{
 
671
    QOrganizerItemGuid guidDetail = detail(QOrganizerItemDetail::TypeGuid);
 
672
    guidDetail.setGuid(guid);
 
673
    saveDetail(&guidDetail);
 
674
}
 
675
 
 
676
/*!
 
677
    Returns the data of the extended detail with the given \a name.
 
678
 */
 
679
QVariant QOrganizerItem::data(const QString &name) const
 
680
{
 
681
    for (int i = 0; i < d->m_details.size(); ++i) {
 
682
        const QOrganizerItemDetail &detail = d->m_details.at(i);
 
683
        if (detail.d->m_detailType == QOrganizerItemDetail::TypeExtendedDetail
 
684
            && detail.d->m_values.value(QOrganizerItemExtendedDetail::FieldName).toString() == name) {
 
685
            return detail.d->m_values.value(QOrganizerItemExtendedDetail::FieldData);
 
686
        }
 
687
    }
 
688
    return QVariant();
 
689
}
 
690
 
 
691
/*!
 
692
    Sets the \a data of a extended detail with the given \a name.
 
693
 */
 
694
void QOrganizerItem::setData(const QString &name, const QVariant &data)
 
695
{
 
696
    for (int i = 0; i < d->m_details.size(); ++i) {
 
697
        const QOrganizerItemDetail &detail = d->m_details.at(i);
 
698
        if (detail.d->m_detailType == QOrganizerItemDetail::TypeExtendedDetail
 
699
            && detail.d->m_values.value(QOrganizerItemExtendedDetail::FieldName).toString() == name) {
 
700
            QOrganizerItemDetail newDetail = d->m_details.at(i);
 
701
            newDetail.d->m_values.insert(QOrganizerItemExtendedDetail::FieldData, data);
 
702
            saveDetail(&newDetail);
 
703
            return;
 
704
        }
 
705
    }
 
706
 
 
707
    QOrganizerItemExtendedDetail newDetail;
 
708
    newDetail.setName(name);
 
709
    newDetail.setData(data);
 
710
    saveDetail(&newDetail);
 
711
}
 
712
 
 
713
/*!
 
714
    \internal
 
715
 */
 
716
void QOrganizerItemData::removeOnly(QOrganizerItemDetail::DetailType detailType)
 
717
{
 
718
    QList<QOrganizerItemDetail>::iterator dit = m_details.begin();
 
719
    while (dit != m_details.end()) {
 
720
        // XXX this doesn't check type or display label
 
721
        if (dit->type() == detailType)
 
722
            dit = m_details.erase(dit);
 
723
        else
 
724
            ++dit;
 
725
    }
 
726
}
 
727
 
 
728
/*!
 
729
    \internal
 
730
 */
 
731
void QOrganizerItemData::removeOnly(const QSet<QOrganizerItemDetail::DetailType> &detailTypes)
 
732
{
 
733
    QList<QOrganizerItemDetail>::iterator dit = m_details.begin();
 
734
    while (dit != m_details.end()) {
 
735
        // XXX this doesn't check type or display label
 
736
        if (detailTypes.contains(dit->type()))
 
737
            dit = m_details.erase(dit);
 
738
        else
 
739
            ++dit;
 
740
    }
 
741
}
 
742
 
 
743
QT_END_NAMESPACE_ORGANIZER