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 QtOrganizer 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 "qorganizeritem.h" |
35 | #include "qorganizeritem_p.h" |
36 | |
37 | #ifndef QT_NO_DATASTREAM |
38 | #include <QtCore/qdatastream.h> |
39 | #endif |
40 | #ifndef QT_NO_DEBUG_STREAM |
41 | #include <QtCore/qdebug.h> |
42 | #endif |
43 | |
44 | #include "qorganizeritemdetail_p.h" |
45 | #include "qorganizeritemdetails.h" |
46 | |
47 | QT_BEGIN_NAMESPACE_ORGANIZER |
48 | |
49 | /*! |
50 | \macro Q_DECLARE_CUSTOM_ORGANIZER_ITEM |
51 | \relates QOrganizerItem |
52 | |
53 | Macro for simplifying declaring convenience leaf classes for QOrganizerItem. |
54 | |
55 | The first argument is the name of the class, and the second argument is the |
56 | item type. |
57 | */ |
58 | |
59 | /*! |
60 | \class QOrganizerItem |
61 | \brief The QOrganizerItem class is the base class of an event, todo, note, or journal entry. |
62 | \inmodule QtOrganizer |
63 | \ingroup organizer-main |
64 | |
65 | A QOrganizerItem object has an id and a collection of details (like a start date and location), as |
66 | well as a collection id which identifies which QOrganizerCollection the item is part of in a manager. |
67 | Each detail (which can have multiple fields) is stored in an appropriate subclass of QOrganizerItemDetail, |
68 | and the QOrganizerItem allows retrieving these details in various ways. QOrganizerItemExtendedDetail is |
69 | supposed to be used to store user specific details that are not pre-defined in the detal leaf classes. |
70 | |
71 | Most clients will want to use the convenient subclasses of QOrganizerItem (i.e., QOrganizerEvent |
72 | (and QOrganizerEventOccurence), QOrganizerTodo (and QOrganizerTodoOccurence), QOrganizerJournal and |
73 | QOrganizerNote) instead of manipulating instances of QOrganizerItem directly. |
74 | |
75 | A QOrganizerItem instance represents the in-memory version of an organizer item. |
76 | It is possible for the contents of a QOrganizerItem to change independently of the contents |
77 | that are stored persistently in a QOrganizerManager. A QOrganizerItem has an id associated |
78 | with it when it is first retrieved from a QOrganizerManager, or after it has been first saved, |
79 | and this allows clients to track changes using the signals in QOrganizerManager. When saved |
80 | in a manager, every item is placed into a QOrganizerCollection in that manager, according |
81 | to the collection id set in the item prior to save (or the default collection if no |
82 | collection id was set in the item). |
83 | |
84 | Different QOrganizerManagers may require an item to have certain details saved in it before |
85 | it can be stored in that manager. By default, every item must have a QOrganizerItemType |
86 | detail which identifies the type of the item. Different subclasses of QOrganizerItem |
87 | (i.e., QOrganizerEvent (and QOrganizerEventOccurence), QOrganizerTodo (and QOrganizerTodoOccurence), |
88 | QOrganizerJournal and QOrganizerNote) may have other mandatory details, depending on the manager. |
89 | |
90 | \sa QOrganizerManager, QOrganizerItemDetail |
91 | */ |
92 | |
93 | /*! |
94 | \fn QOrganizerItem::operator!=(const QOrganizerItem &other) const |
95 | |
96 | Returns true if this organizer item's id or details are different to those of the \a other organizer item. |
97 | */ |
98 | |
99 | /*! |
100 | Construct an empty organizer item. |
101 | |
102 | The organizer item will have an empty item ID, and an empty collection ID. It's of type \l QOrganizerItemType::TypeUndefined. |
103 | */ |
104 | QOrganizerItem::QOrganizerItem() |
105 | : d(new QOrganizerItemData) |
106 | { |
107 | QOrganizerItemType organizeritemType; |
108 | organizeritemType.setType(QOrganizerItemType::TypeUndefined); |
109 | d->m_details.append(t: organizeritemType); |
110 | } |
111 | |
112 | /*! |
113 | Constructs an item that is a copy of \a other. |
114 | */ |
115 | QOrganizerItem::QOrganizerItem(const QOrganizerItem &other) |
116 | : d(other.d) |
117 | { |
118 | } |
119 | |
120 | /*! |
121 | \internal |
122 | |
123 | Constructs a new, empty item of the given type \a type. |
124 | */ |
125 | QOrganizerItem::QOrganizerItem(QOrganizerItemType::ItemType type) |
126 | : d(new QOrganizerItemData) |
127 | { |
128 | QOrganizerItemType organizeritemType; |
129 | organizeritemType.setType(type); |
130 | d->m_details.append(t: organizeritemType); |
131 | } |
132 | |
133 | /*! |
134 | \internal |
135 | |
136 | Constructs an item that is a copy of \a other if \a other is of the expected type |
137 | identified by \a expectedType, else constructs a new, empty item of the |
138 | type identified by the \a expectedType. |
139 | |
140 | The \a expectedType pointer must be valid for the lifetime of the program. |
141 | */ |
142 | QOrganizerItem::QOrganizerItem(const QOrganizerItem &other, QOrganizerItemType::ItemType expectedType) |
143 | { |
144 | if (other.type() == expectedType) { |
145 | d = other.d; |
146 | } else { |
147 | d = new QOrganizerItemData; |
148 | setType(expectedType); |
149 | } |
150 | } |
151 | |
152 | /*! |
153 | \internal |
154 | |
155 | Assigns this item to \a other if the type of \a other is that identified |
156 | by the given \a expectedType, else assigns this item to be a new, empty |
157 | item of the type identified by the given \a expectedType |
158 | */ |
159 | QOrganizerItem &QOrganizerItem::assign(const QOrganizerItem &other, QOrganizerItemType::ItemType expectedType) |
160 | { |
161 | if (this != &other) { |
162 | if (other.type() == expectedType) { |
163 | d = other.d; |
164 | } else { |
165 | d = new QOrganizerItemData; |
166 | setType(expectedType); |
167 | } |
168 | } |
169 | return *this; |
170 | } |
171 | |
172 | |
173 | /*! |
174 | Returns true if this QOrganizerItem is empty, false if not. |
175 | |
176 | Note that the type detail of the organizer item is irrelevant. |
177 | */ |
178 | bool QOrganizerItem::isEmpty() const |
179 | { |
180 | return (d->m_details.count() == 1); |
181 | } |
182 | |
183 | /*! |
184 | Removes all details of the organizer item, and resets the type to be \l QOrganizerItemType::TypeUndefined. |
185 | */ |
186 | void QOrganizerItem::clearDetails() |
187 | { |
188 | d->m_details.clear(); |
189 | |
190 | QOrganizerItemType organizeritemType; |
191 | organizeritemType.setType(QOrganizerItemType::TypeUndefined); |
192 | d->m_details.append(t: organizeritemType); |
193 | } |
194 | |
195 | /*! |
196 | Replace the contents of this organizer item with the \a other. |
197 | */ |
198 | QOrganizerItem &QOrganizerItem::operator=(const QOrganizerItem &other) |
199 | { |
200 | d = other.d; |
201 | return *this; |
202 | } |
203 | |
204 | /*! |
205 | Frees the memory used by this item. |
206 | */ |
207 | QOrganizerItem::~QOrganizerItem() |
208 | { |
209 | } |
210 | |
211 | /*! |
212 | Returns the QOrganizerItemId that identifies this organizer item. |
213 | |
214 | This may have been set when the organizer item was retrieved from |
215 | a particular manager, or when the organizer item was first saved |
216 | in a manager. The QOrganizerItemId is only valid within a specific |
217 | manager. See \l QOrganizerManager::saveItem() for more |
218 | information. |
219 | */ |
220 | QOrganizerItemId QOrganizerItem::id() const |
221 | { |
222 | return d->m_id; |
223 | } |
224 | |
225 | /*! |
226 | Returns the id of the collection which this item is part of, in the manager |
227 | in which the item has been saved, if the item has previously been saved in |
228 | a manager. If the item has not previously been saved in a manager, this function |
229 | will return the id of the collection into which the client wishes the item to be |
230 | saved when \l QOrganizerManager::saveItem() is called, which is set by calling |
231 | \l setId(); otherwise, returns a null id. |
232 | |
233 | An item always belongs to exactly one collection in a particular manager after it |
234 | has been saved in the manager. If the item has previously been saved in the manager, |
235 | in a particular collection, and the client sets the collection id of the item to |
236 | the id of a different collection within that manager and then resaves the item, |
237 | the item will be moved from its original collection into the specified collection |
238 | if the move operation is supported by the manager; otherwise, the |
239 | \l QOrganizerManager::saveItem() operation will fail and calling |
240 | \l QOrganizerManager::error() will return \c QOrganizerManager::NotSupportedError. |
241 | */ |
242 | QOrganizerCollectionId QOrganizerItem::collectionId() const |
243 | { |
244 | return d->m_collectionId; |
245 | } |
246 | |
247 | /*! |
248 | Sets the id of the collection into which the client wishes the item to be saved |
249 | to the given \a collectionId. |
250 | |
251 | If the given \a collectionId is the null collection id, the client is specifying |
252 | that the item should be saved into the collection in which the item is already |
253 | saved (if the item has previously been saved in the manager, without having been |
254 | removed since), or into the default collection of the manager (if the item has |
255 | not previously been saved in the manager, or has been removed since the last time |
256 | it was saved). |
257 | |
258 | If the item has previously been saved in a particular manager, and the given |
259 | \a collectionId is the id of a different collection than the one which the |
260 | item is currently a part of in that manager, saving the item with |
261 | \l QOrganizerManager::saveItem() will move the item from its original |
262 | collection to the collection whose id is \a collectionId, if \a collectionId |
263 | identifies a valid collection and the operation is supported by the manager. |
264 | */ |
265 | void QOrganizerItem::setCollectionId(const QOrganizerCollectionId &collectionId) |
266 | { |
267 | d->m_collectionId = collectionId; |
268 | } |
269 | |
270 | /*! |
271 | Sets the id of this organizer item to \a id. |
272 | |
273 | Note that this only affects this object, not any corresponding structures stored |
274 | by a QOrganizerManager. |
275 | |
276 | If you change the id of a organizer item and save the organizer item |
277 | in a manager, the previously existing organizer item will still |
278 | exist. You can do this to create copies (possibly modified) |
279 | of an existing organizer item, or to save a organizer item in a different manager. |
280 | |
281 | \sa QOrganizerManager::saveItem() |
282 | */ |
283 | void QOrganizerItem::setId(const QOrganizerItemId &id) |
284 | { |
285 | d->m_id = id; |
286 | // TODO - reset collection id? |
287 | } |
288 | |
289 | /*! |
290 | Returns the first detail stored in the organizer item with the given \a detailType. If the |
291 | given \a detailType is TypeUndefined, it returns the first detail found. |
292 | */ |
293 | QOrganizerItemDetail QOrganizerItem::detail(QOrganizerItemDetail::DetailType detailType) const |
294 | { |
295 | if (detailType == QOrganizerItemDetail::TypeUndefined) |
296 | return d->m_details.first(); |
297 | |
298 | for (int i = 0; i < d->m_details.size(); i++) { |
299 | const QOrganizerItemDetail &existing = d->m_details.at(i); |
300 | if (existing.d->m_detailType == detailType) |
301 | return existing; |
302 | } |
303 | |
304 | return QOrganizerItemDetail(); |
305 | } |
306 | |
307 | /*! |
308 | Returns a list of details with the given \a detailType. If the given \a detailType is of TypeUndefined, |
309 | it returns all the details. |
310 | */ |
311 | QList<QOrganizerItemDetail> QOrganizerItem::details(QOrganizerItemDetail::DetailType detailType) const |
312 | { |
313 | if (detailType == QOrganizerItemDetail::TypeUndefined) |
314 | return d->m_details; |
315 | |
316 | QList<QOrganizerItemDetail> sublist; |
317 | for (int i = 0; i < d->m_details.size(); i++) { |
318 | const QOrganizerItemDetail &existing = d->m_details.at(i); |
319 | if (existing.d->m_detailType == detailType) |
320 | sublist.append(t: existing); |
321 | } |
322 | return sublist; |
323 | } |
324 | |
325 | /*! |
326 | Saves the given \a detail in the list of stored details, and sets the detail's id. |
327 | If another detail of the same type and id has been previously saved in |
328 | this organizer item, that detail is overwritten. Otherwise, a new id is generated |
329 | and set in the detail, and the detail is added to the organizer item. |
330 | |
331 | If \a detail is a QOrganizerItemType, the existing organizer item type will |
332 | be overwritten with \a detail. There is never more than one organizer item type |
333 | in a organizer item. |
334 | |
335 | Returns true if the detail was saved successfully, otherwise returns false. |
336 | |
337 | Note that the caller retains ownership of the detail. |
338 | */ |
339 | bool QOrganizerItem::saveDetail(QOrganizerItemDetail *detail) |
340 | { |
341 | if (!detail) |
342 | return false; |
343 | |
344 | // we only allow one instance of these details per item |
345 | if (detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeItemType |
346 | || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeDescription |
347 | || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeDisplayLabel |
348 | || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeClassification |
349 | || detail->d.constData()->m_detailType == QOrganizerItemDetail::TypeVersion) { |
350 | for (int i = 0; i < d.constData()->m_details.size(); i++) { |
351 | if (detail->d.constData()->m_detailType == d.constData()->m_details.at(i).d.constData()->m_detailType) { |
352 | d->m_details.replace(i, t: *detail); |
353 | return true; |
354 | } |
355 | } |
356 | // doesn't already exist; append it. |
357 | d->m_details.append(t: *detail); |
358 | return true; |
359 | } |
360 | |
361 | // try to find the "old version" of this field |
362 | // ie, the one with the same type and id, but different value or attributes. |
363 | for (int i = 0; i < d.constData()->m_details.size(); i++) { |
364 | const QOrganizerItemDetail& curr = d.constData()->m_details.at(i); |
365 | if (detail->d.constData()->m_detailType == curr.d.constData()->m_detailType && detail->d.constData()->m_id == curr.d.constData()->m_id) { |
366 | // update the detail constraints of the supplied detail |
367 | // Found the old version. Replace it with this one. |
368 | d->m_details[i] = *detail; |
369 | return true; |
370 | } |
371 | } |
372 | // this is a new detail! add it to the organizer item. |
373 | d->m_details.append(t: *detail); |
374 | return true; |
375 | } |
376 | |
377 | /*! |
378 | Removes the \a detail from the organizer item. |
379 | |
380 | The detail in the organizer item which has the same key as that of the given \a detail |
381 | will be removed if it exists. Only the key is used for comparison - that is, the |
382 | information in the detail may be different. |
383 | |
384 | Returns true if the detail was removed successfully, false if an error occurred. |
385 | |
386 | Note that the caller retains ownership of the detail. |
387 | */ |
388 | bool QOrganizerItem::removeDetail(QOrganizerItemDetail *detail) |
389 | { |
390 | if (!detail) |
391 | return false; |
392 | |
393 | // find the detail stored in the organizer item which has the same key as the detail argument |
394 | int removeIndex = -1; |
395 | for (int i = 0; i < d.constData()->m_details.size(); i++) { |
396 | if (d.constData()->m_details.at(i).key() == detail->key()) { |
397 | removeIndex = i; |
398 | break; |
399 | } |
400 | } |
401 | |
402 | // make sure the detail exists (in some form) in the organizer item. |
403 | if (removeIndex < 0) |
404 | return false; |
405 | |
406 | // Type -detail is specific case which cannot be deleted |
407 | if (QOrganizerItemDetail::TypeItemType == detail->d.constData()->m_detailType) |
408 | return false; |
409 | |
410 | if (!d.constData()->m_details.contains(t: *detail)) |
411 | return false; |
412 | |
413 | // then remove the detail. |
414 | d->m_details.removeAt(i: removeIndex); |
415 | return true; |
416 | } |
417 | |
418 | /*! |
419 | Returns true if this organizer item is equal to the \a other organizer item, false if either the |
420 | id, collection id or stored details are not the same. |
421 | */ |
422 | bool QOrganizerItem::operator==(const QOrganizerItem &other) const |
423 | { |
424 | if (d == other.d) |
425 | return true; |
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 | foreach (const QOrganizerItemDetail &detail, other.d->m_details) { |
435 | if (!searchList.removeOne(t: detail)) |
436 | return false; |
437 | } |
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(id: key.id()); |
450 | hash += qHash(id: key.collectionId()); |
451 | foreach (const QOrganizerItemDetail &detail, key.details()) |
452 | hash += qHash(key: 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(idString: itemIdString)); |
500 | item.setCollectionId(QOrganizerCollectionId::fromString(idString: 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(i: 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(t: organizeritemType); |
528 | } else { |
529 | // type is always the first detail |
530 | d->m_details.first().setValue(field: QOrganizerItemType::FieldType, value: type); |
531 | } |
532 | } |
533 | |
534 | /*! |
535 | Returns the display label of the item. |
536 | */ |
537 | QString QOrganizerItem::displayLabel() const |
538 | { |
539 | QOrganizerItemDisplayLabel dl = detail(detailType: 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(detailType: QOrganizerItemDetail::TypeDisplayLabel); |
549 | dl.setLabel(label); |
550 | saveDetail(detail: &dl); |
551 | } |
552 | |
553 | /*! |
554 | Returns the human-readable description of the item. |
555 | */ |
556 | QString QOrganizerItem::description() const |
557 | { |
558 | QOrganizerItemDescription descr = detail(detailType: 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(detailType: QOrganizerItemDetail::TypeDescription); |
568 | descr.setDescription(description); |
569 | saveDetail(detail: &descr); |
570 | } |
571 | |
572 | /*! |
573 | Returns the list of comments of this item. |
574 | */ |
575 | QStringList QOrganizerItem::() const |
576 | { |
577 | QStringList ; |
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(t: detail.d->m_values.value(akey: QOrganizerItemComment::FieldComment).toString()); |
582 | } |
583 | return commentList; |
584 | } |
585 | |
586 | /*! |
587 | Removes all comments of this item. |
588 | */ |
589 | void QOrganizerItem::() |
590 | { |
591 | d->removeOnly(detailType: QOrganizerItemDetail::TypeComment); |
592 | } |
593 | |
594 | /*! |
595 | Sets the list of comments associated with the item to \a comments. |
596 | */ |
597 | void QOrganizerItem::(const QStringList &) |
598 | { |
599 | d->removeOnly(detailType: QOrganizerItemDetail::TypeComment); |
600 | foreach (const QString &, comments) |
601 | addComment(comment); |
602 | } |
603 | |
604 | /*! |
605 | Adds the \a comment to this item |
606 | */ |
607 | void QOrganizerItem::(const QString &) |
608 | { |
609 | QOrganizerItemComment detail; |
610 | detail.setComment(comment); |
611 | saveDetail(detail: &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(t: detail.d->m_values.value(akey: 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(detailType: 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(detail: &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(detailType: 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(detailType: 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(detailType: QOrganizerItemDetail::TypeGuid); |
672 | guidDetail.setGuid(guid); |
673 | saveDetail(detail: &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(akey: QOrganizerItemExtendedDetail::FieldName).toString() == name) { |
685 | return detail.d->m_values.value(akey: 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(akey: QOrganizerItemExtendedDetail::FieldName).toString() == name) { |
700 | QOrganizerItemDetail newDetail = d->m_details.at(i); |
701 | newDetail.d->m_values.insert(akey: QOrganizerItemExtendedDetail::FieldData, avalue: data); |
702 | saveDetail(detail: &newDetail); |
703 | return; |
704 | } |
705 | } |
706 | |
707 | QOrganizerItemExtendedDetail newDetail; |
708 | newDetail.setName(name); |
709 | newDetail.setData(data); |
710 | saveDetail(detail: &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(it: 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(value: dit->type())) |
737 | dit = m_details.erase(it: dit); |
738 | else |
739 | ++dit; |
740 | } |
741 | } |
742 | |
743 | QT_END_NAMESPACE_ORGANIZER |
744 | |