data/ICalTodoCodec.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ICalTodoCodec.h" | ||
| 2 | #include "ICalEventCodec.h" | ||
| 3 | #include "util/MessageId.h" | ||
| 4 | #include <QLoggingCategory> | ||
| 5 | #include <QSet> | ||
| 6 | #include <algorithm> | ||
| 7 | |||
| 8 |
3/7✓ Branch 2 → 3 taken 2 times.
✗ Branch 2 → 8 not taken.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
2 | Q_LOGGING_CATEGORY(lcTodoCodec, "mailjd.tasks.codec") |
| 9 | namespace ICalTodoCodec { | ||
| 10 | 966 | CalendarTask taskFromComponent(const ICal::Component &component, const ICalTime::ZoneResolver &resolver) { | |
| 11 | 966 | CalendarTask task; | |
| 12 |
4/4✓ Branch 3 → 4 taken 966 times.
✓ Branch 4 → 5 taken 966 times.
✓ Branch 5 → 6 taken 966 times.
✓ Branch 6 → 7 taken 966 times.
|
966 | task.uid = ICal::unescapeText(component.value("UID")).trimmed(); |
| 13 |
3/3✓ Branch 12 → 13 taken 966 times.
✓ Branch 13 → 14 taken 966 times.
✓ Branch 14 → 15 taken 966 times.
|
966 | task.summary = ICal::unescapeText(component.value("SUMMARY")); |
| 14 |
3/3✓ Branch 19 → 20 taken 966 times.
✓ Branch 20 → 21 taken 966 times.
✓ Branch 21 → 22 taken 966 times.
|
966 | task.description = ICal::unescapeText(component.value("DESCRIPTION")); |
| 15 |
4/4✓ Branch 26 → 27 taken 966 times.
✓ Branch 27 → 28 taken 966 times.
✓ Branch 28 → 29 taken 966 times.
✓ Branch 29 → 30 taken 966 times.
|
966 | task.status = component.value("STATUS").trimmed().toUpper(); |
| 16 |
2/2✓ Branch 36 → 37 taken 93 times.
✓ Branch 36 → 44 taken 873 times.
|
1059 | if (task.status.isEmpty()) task.status = QStringLiteral("NEEDS-ACTION"); |
| 17 |
3/3✓ Branch 44 → 45 taken 966 times.
✓ Branch 45 → 46 taken 966 times.
✓ Branch 46 → 47 taken 966 times.
|
966 | task.priority = component.value("PRIORITY").toInt(); |
| 18 |
3/3✓ Branch 49 → 50 taken 966 times.
✓ Branch 50 → 51 taken 966 times.
✓ Branch 51 → 52 taken 966 times.
|
966 | task.percentComplete = component.value("PERCENT-COMPLETE").toInt(); |
| 19 | 4830 | const auto date = [&](const QString &name, QDateTime *stamp, bool *dateOnly = nullptr) { | |
| 20 |
2/2✓ Branch 3 → 4 taken 1943 times.
✓ Branch 3 → 10 taken 2887 times.
|
4830 | if (const auto *property = component.property(name)) { |
| 21 |
1/1✓ Branch 4 → 5 taken 1943 times.
|
1943 | const auto parsed = ICalTime::parseProperty(*property, resolver); |
| 22 | 1943 | *stamp = parsed.dateTime; | |
| 23 |
2/2✓ Branch 6 → 7 taken 528 times.
✓ Branch 6 → 8 taken 1415 times.
|
1943 | if (dateOnly) *dateOnly = parsed.dateOnly; |
| 24 | 1943 | } | |
| 25 | 4830 | }; | |
| 26 |
2/2✓ Branch 54 → 55 taken 966 times.
✓ Branch 55 → 56 taken 966 times.
|
966 | date("DUE", &task.due, &task.dueAllDay); |
| 27 |
2/2✓ Branch 57 → 58 taken 966 times.
✓ Branch 58 → 59 taken 966 times.
|
966 | date("DTSTART", &task.dtStart, &task.startAllDay); |
| 28 |
2/2✓ Branch 60 → 61 taken 966 times.
✓ Branch 61 → 62 taken 966 times.
|
966 | date("COMPLETED", &task.completedAt); |
| 29 |
2/2✓ Branch 63 → 64 taken 966 times.
✓ Branch 64 → 65 taken 966 times.
|
966 | date("CREATED", &task.created); |
| 30 |
2/2✓ Branch 66 → 67 taken 966 times.
✓ Branch 67 → 68 taken 966 times.
|
966 | date("LAST-MODIFIED", &task.lastModified); |
| 31 |
4/4✓ Branch 69 → 70 taken 966 times.
✓ Branch 70 → 71 taken 966 times.
✓ Branch 72 → 73 taken 95 times.
✓ Branch 72 → 94 taken 871 times.
|
966 | if (const auto *organizer = component.property("ORGANIZER")) |
| 32 |
14/19✓ Branch 73 → 74 taken 95 times.
✓ Branch 74 → 75 taken 95 times.
✓ Branch 76 → 77 taken 3 times.
✓ Branch 76 → 83 taken 92 times.
✓ Branch 77 → 78 taken 3 times.
✓ Branch 78 → 79 taken 3 times.
✓ Branch 79 → 80 taken 3 times.
✗ Branch 79 → 81 not taken.
✓ Branch 82 → 85 taken 3 times.
✓ Branch 83 → 84 taken 92 times.
✓ Branch 84 → 85 taken 92 times.
✓ Branch 87 → 88 taken 92 times.
✓ Branch 87 → 89 taken 3 times.
✓ Branch 89 → 90 taken 3 times.
✓ Branch 89 → 91 taken 92 times.
✗ Branch 276 → 277 not taken.
✗ Branch 276 → 278 not taken.
✗ Branch 280 → 281 not taken.
✗ Branch 280 → 282 not taken.
|
95 | task.organizer = organizer->parameter("CN").isEmpty() ? organizer->value.mid(organizer->value.startsWith("mailto:", Qt::CaseInsensitive) ? 7 : 0) : organizer->parameter("CN"); |
| 33 |
4/4✓ Branch 94 → 95 taken 966 times.
✓ Branch 95 → 96 taken 966 times.
✓ Branch 96 → 97 taken 966 times.
✓ Branch 97 → 98 taken 966 times.
|
966 | task.relatedMessageId = MessageId::canonicalFirst(ICal::unescapeText(component.value("X-MAILJD-MESSAGE-ID"))); |
| 34 |
2/2✓ Branch 103 → 104 taken 966 times.
✓ Branch 104 → 105 taken 966 times.
|
966 | task.rrule = component.value("RRULE"); |
| 35 |
6/6✓ Branch 108 → 109 taken 966 times.
✓ Branch 109 → 110 taken 966 times.
✓ Branch 111 → 112 taken 966 times.
✓ Branch 112 → 113 taken 966 times.
✓ Branch 139 → 114 taken 184 times.
✓ Branch 139 → 140 taken 782 times.
|
966 | for (const auto &property : component.propertiesNamed("RELATED-TO")) { |
| 36 |
3/3✓ Branch 115 → 116 taken 184 times.
✓ Branch 116 → 117 taken 184 times.
✓ Branch 117 → 118 taken 184 times.
|
184 | const QString type = property.parameter("RELTYPE").toUpper(); |
| 37 |
4/6✓ Branch 121 → 122 taken 168 times.
✓ Branch 121 → 125 taken 16 times.
✓ Branch 124 → 125 taken 168 times.
✗ Branch 124 → 126 not taken.
✓ Branch 127 → 128 taken 184 times.
✗ Branch 127 → 132 not taken.
|
184 | if (type.isEmpty() || type == QLatin1String("PARENT")) { |
| 38 |
1/1✓ Branch 128 → 129 taken 184 times.
|
184 | task.parentUid = ICal::unescapeText(property.value); break; |
| 39 | } | ||
| 40 | 1150 | } | |
| 41 |
6/6✓ Branch 141 → 142 taken 966 times.
✓ Branch 142 → 143 taken 966 times.
✓ Branch 144 → 145 taken 966 times.
✓ Branch 145 → 146 taken 966 times.
✓ Branch 167 → 147 taken 274 times.
✓ Branch 167 → 168 taken 966 times.
|
1240 | for (const auto &property : component.propertiesNamed("CATEGORIES")) |
| 42 |
5/5✓ Branch 148 → 149 taken 274 times.
✓ Branch 149 → 150 taken 274 times.
✓ Branch 150 → 151 taken 274 times.
✓ Branch 163 → 152 taken 399 times.
✓ Branch 163 → 164 taken 274 times.
|
673 | for (const auto &value : ICal::splitValues(property.value)) |
| 43 |
4/5✓ Branch 153 → 154 taken 399 times.
✓ Branch 156 → 157 taken 399 times.
✗ Branch 156 → 161 not taken.
✓ Branch 157 → 158 taken 399 times.
✓ Branch 158 → 159 taken 399 times.
|
1639 | if (!task.tags.contains(ICal::unescapeText(value))) task.tags << ICal::unescapeText(value); |
| 44 |
4/4✓ Branch 169 → 170 taken 966 times.
✓ Branch 170 → 171 taken 966 times.
✓ Branch 171 → 172 taken 966 times.
✓ Branch 172 → 173 taken 966 times.
|
966 | task.sortOrder = std::clamp(component.value("X-APPLE-SORT-ORDER").toLongLong(), -kTaskSortOrderLimit, |
| 45 | kTaskSortOrderLimit); | ||
| 46 |
2/2✓ Branch 175 → 176 taken 966 times.
✓ Branch 176 → 177 taken 966 times.
|
966 | task.previousStatus = component.value("X-MAILJD-PREVIOUS-STATUS"); |
| 47 |
3/3✓ Branch 180 → 181 taken 966 times.
✓ Branch 181 → 182 taken 966 times.
✓ Branch 182 → 183 taken 966 times.
|
966 | task.previousPercent = component.value("X-MAILJD-PREVIOUS-PERCENT").toInt(); |
| 48 |
1/1✓ Branch 185 → 186 taken 966 times.
|
966 | const QDateTime anchor = task.dtStart.isValid() |
| 49 |
3/5✓ Branch 186 → 187 taken 119 times.
✓ Branch 186 → 192 taken 847 times.
✗ Branch 187 → 188 not taken.
✓ Branch 187 → 191 taken 119 times.
✗ Branch 188 → 189 not taken.
|
966 | ? task.startAllDay ? QDateTime(task.dtStart.date(),QTime(0,0)) : task.dtStart |
| 50 |
5/7✗ Branch 189 → 190 not taken.
✗ Branch 190 → 197 not taken.
✓ Branch 192 → 193 taken 117 times.
✓ Branch 192 → 196 taken 730 times.
✓ Branch 193 → 194 taken 117 times.
✓ Branch 194 → 195 taken 117 times.
✓ Branch 195 → 197 taken 117 times.
|
966 | : task.dueAllDay ? QDateTime(task.due.date(),QTime(0,0)) : task.due; |
| 51 |
5/5✓ Branch 197 → 198 taken 162 times.
✓ Branch 197 → 201 taken 804 times.
✓ Branch 198 → 199 taken 162 times.
✓ Branch 199 → 200 taken 162 times.
✓ Branch 200 → 202 taken 162 times.
|
966 | const QDateTime end = task.dueAllDay ? QDateTime(task.due.date(),QTime(0,0)) : task.due; |
| 52 |
1/1✓ Branch 202 → 203 taken 966 times.
|
966 | task.alarmTimes = ICalEventCodec::alarmTimes(component, anchor, end, resolver); |
| 53 |
1/1✓ Branch 205 → 206 taken 966 times.
|
966 | task.icalRaw = ICal::serialize(component); |
| 54 | 966 | return task; | |
| 55 | 966 | } | |
| 56 | |||
| 57 | 908 | bool parseResource(const QString &text, Resource *resource, QString *error) { | |
| 58 |
1/2✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 908 times.
|
908 | if (!resource) return false; |
| 59 |
1/1✓ Branch 7 → 8 taken 908 times.
|
908 | resource->calendar = ICal::parseFirst(text, QStringLiteral("VCALENDAR"), error); |
| 60 |
1/1✓ Branch 12 → 13 taken 908 times.
|
908 | resource->tasks.clear(); |
| 61 |
2/2✓ Branch 14 → 15 taken 2 times.
✓ Branch 14 → 16 taken 906 times.
|
908 | if (resource->calendar.name.isEmpty()) return false; |
| 62 |
1/1✓ Branch 16 → 17 taken 906 times.
|
906 | const ICalTime::ZoneResolver resolver(resource->calendar); |
| 63 |
6/6✓ Branch 17 → 18 taken 906 times.
✓ Branch 18 → 19 taken 906 times.
✓ Branch 20 → 21 taken 906 times.
✓ Branch 21 → 22 taken 906 times.
✓ Branch 48 → 23 taken 341 times.
✓ Branch 48 → 49 taken 906 times.
|
1247 | for (const auto &component : resource->calendar.componentsNamed("VTODO")) { |
| 64 |
1/1✓ Branch 24 → 25 taken 341 times.
|
341 | auto task = taskFromComponent(component, resolver); |
| 65 |
7/7✓ Branch 26 → 27 taken 1 time.
✓ Branch 26 → 38 taken 340 times.
✓ Branch 27 → 28 taken 1 time.
✓ Branch 31 → 32 taken 1 time.
✓ Branch 32 → 33 taken 1 time.
✓ Branch 36 → 29 taken 1 time.
✓ Branch 36 → 37 taken 1 time.
|
342 | if (task.uid.isEmpty()) { qCWarning(lcTodoCodec) << "Skipping VTODO without UID"; continue; } |
| 66 | 340 | task.resourceIcal = text; | |
| 67 |
1/1✓ Branch 39 → 40 taken 340 times.
|
340 | resource->tasks << task; |
| 68 | 1247 | } | |
| 69 | 906 | return true; | |
| 70 | 906 | } | |
| 71 | |||
| 72 | namespace { | ||
| 73 | 1378 | bool sameDate(const QDateTime &a, bool aDate, const QDateTime &b, bool bDate) { | |
| 74 |
6/6✓ Branch 2 → 3 taken 1360 times.
✓ Branch 2 → 6 taken 18 times.
✓ Branch 5 → 6 taken 33 times.
✓ Branch 5 → 7 taken 1327 times.
✓ Branch 8 → 9 taken 51 times.
✓ Branch 8 → 10 taken 1327 times.
|
1378 | if (aDate != bDate || a.isValid() != b.isValid()) return false; |
| 75 |
2/2✓ Branch 11 → 12 taken 1087 times.
✓ Branch 11 → 13 taken 240 times.
|
1327 | if (!a.isValid()) return true; |
| 76 |
14/19✓ Branch 13 → 14 taken 76 times.
✓ Branch 13 → 18 taken 164 times.
✓ Branch 14 → 15 taken 76 times.
✓ Branch 15 → 16 taken 76 times.
✓ Branch 18 → 19 taken 164 times.
✓ Branch 19 → 20 taken 150 times.
✓ Branch 19 → 25 taken 14 times.
✓ Branch 20 → 21 taken 150 times.
✓ Branch 21 → 22 taken 150 times.
✓ Branch 23 → 24 taken 150 times.
✗ Branch 23 → 25 not taken.
✓ Branch 28 → 29 taken 150 times.
✓ Branch 28 → 30 taken 90 times.
✓ Branch 30 → 31 taken 150 times.
✓ Branch 30 → 32 taken 90 times.
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 36 not taken.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
|
240 | return aDate ? a.date() == b.date() : a == b && ICalTime::zoneId(a, false) == ICalTime::zoneId(b, false); |
| 77 | } | ||
| 78 | 579 | void writeDate(ICal::Component *component, const QString &name, const QDateTime &stamp, | |
| 79 | bool dateOnly, const ICalTime::ZoneResolver &resolver) { | ||
| 80 |
4/4✓ Branch 2 → 3 taken 579 times.
✓ Branch 3 → 4 taken 380 times.
✓ Branch 3 → 6 taken 199 times.
✓ Branch 4 → 5 taken 380 times.
|
579 | if (!stamp.isValid()) { component->removeProperties(name); return; } |
| 81 | 199 | ICal::Property property; | |
| 82 |
3/3✓ Branch 6 → 7 taken 199 times.
✓ Branch 7 → 8 taken 9 times.
✓ Branch 7 → 9 taken 190 times.
|
199 | if (const auto *existing = component->property(name)) property = *existing; |
| 83 | 199 | property.name = name; | |
| 84 | 199 | QString tzid; | |
| 85 |
3/3✓ Branch 10 → 11 taken 199 times.
✓ Branch 11 → 12 taken 35 times.
✓ Branch 11 → 38 taken 164 times.
|
199 | if (stamp.timeSpec() == Qt::TimeZone) { |
| 86 |
2/2✓ Branch 12 → 13 taken 35 times.
✓ Branch 13 → 14 taken 35 times.
|
35 | tzid = property.parameter("TZID"); |
| 87 |
15/19✓ Branch 18 → 19 taken 5 times.
✓ Branch 18 → 23 taken 30 times.
✓ Branch 19 → 20 taken 5 times.
✓ Branch 20 → 21 taken 5 times.
✓ Branch 22 → 23 taken 1 time.
✓ Branch 22 → 24 taken 4 times.
✓ Branch 25 → 26 taken 5 times.
✓ Branch 25 → 27 taken 30 times.
✓ Branch 27 → 28 taken 5 times.
✓ Branch 27 → 29 taken 30 times.
✓ Branch 29 → 30 taken 31 times.
✓ Branch 29 → 38 taken 4 times.
✓ Branch 30 → 31 taken 31 times.
✓ Branch 31 → 32 taken 31 times.
✓ Branch 32 → 33 taken 31 times.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 51 not taken.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
|
35 | if (tzid.isEmpty() || resolver.resolve(tzid) != stamp.timeZone()) tzid = QString::fromUtf8(stamp.timeZone().id()); |
| 88 | } | ||
| 89 |
1/1✓ Branch 38 → 39 taken 199 times.
|
199 | ICalTime::writeProperty(&property, stamp, dateOnly, tzid); |
| 90 |
1/1✓ Branch 39 → 40 taken 199 times.
|
199 | component->setProperty(property); |
| 91 | 199 | } | |
| 92 | } | ||
| 93 | |||
| 94 | 365 | ICal::Component taskComponent(const CalendarTask &task, const ICalTime::ZoneResolver &resolver) { | |
| 95 | 365 | ICal::Component component; | |
| 96 |
2/2✓ Branch 3 → 4 taken 228 times.
✓ Branch 3 → 15 taken 137 times.
|
365 | if (!task.icalRaw.isEmpty()) { |
| 97 |
1/1✓ Branch 7 → 8 taken 228 times.
|
228 | component = ICal::parseFirst(task.icalRaw, QStringLiteral("VTODO")); |
| 98 | // Never replace an unreadable remote resource with a partial fresh one. | ||
| 99 |
1/2✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 228 times.
|
228 | if (component.name.isEmpty()) return {}; |
| 100 | } | ||
| 101 | 365 | const bool fresh = component.name.isEmpty(); | |
| 102 |
3/63✓ Branch 16 → 17 taken 137 times.
✓ Branch 16 → 23 taken 228 times.
✓ Branch 23 → 24 taken 228 times.
✗ Branch 349 → 350 not taken.
✗ Branch 349 → 352 not taken.
✗ Branch 350 → 351 not taken.
✗ Branch 350 → 352 not taken.
✗ Branch 353 → 354 not taken.
✗ Branch 353 → 356 not taken.
✗ Branch 354 → 355 not taken.
✗ Branch 354 → 356 not taken.
✗ Branch 357 → 358 not taken.
✗ Branch 357 → 360 not taken.
✗ Branch 358 → 359 not taken.
✗ Branch 358 → 360 not taken.
✗ Branch 361 → 362 not taken.
✗ Branch 361 → 364 not taken.
✗ Branch 362 → 363 not taken.
✗ Branch 362 → 364 not taken.
✗ Branch 365 → 366 not taken.
✗ Branch 365 → 368 not taken.
✗ Branch 366 → 367 not taken.
✗ Branch 366 → 368 not taken.
✗ Branch 369 → 370 not taken.
✗ Branch 369 → 372 not taken.
✗ Branch 370 → 371 not taken.
✗ Branch 370 → 372 not taken.
✗ Branch 373 → 374 not taken.
✗ Branch 373 → 376 not taken.
✗ Branch 374 → 375 not taken.
✗ Branch 374 → 376 not taken.
✗ Branch 377 → 378 not taken.
✗ Branch 377 → 380 not taken.
✗ Branch 378 → 379 not taken.
✗ Branch 378 → 380 not taken.
✗ Branch 381 → 382 not taken.
✗ Branch 381 → 384 not taken.
✗ Branch 382 → 383 not taken.
✗ Branch 382 → 384 not taken.
✗ Branch 385 → 386 not taken.
✗ Branch 385 → 388 not taken.
✗ Branch 386 → 387 not taken.
✗ Branch 386 → 388 not taken.
✗ Branch 389 → 390 not taken.
✗ Branch 389 → 392 not taken.
✗ Branch 390 → 391 not taken.
✗ Branch 390 → 392 not taken.
✗ Branch 393 → 394 not taken.
✗ Branch 393 → 396 not taken.
✗ Branch 394 → 395 not taken.
✗ Branch 394 → 396 not taken.
✗ Branch 397 → 398 not taken.
✗ Branch 397 → 400 not taken.
✗ Branch 398 → 399 not taken.
✗ Branch 398 → 400 not taken.
✗ Branch 401 → 402 not taken.
✗ Branch 401 → 404 not taken.
✗ Branch 402 → 403 not taken.
✗ Branch 402 → 404 not taken.
✗ Branch 405 → 406 not taken.
✗ Branch 405 → 408 not taken.
✗ Branch 406 → 407 not taken.
✗ Branch 406 → 408 not taken.
|
365 | const auto before = fresh ? CalendarTask{} : taskFromComponent(component, resolver); |
| 103 |
5/5✓ Branch 24 → 25 taken 137 times.
✓ Branch 24 → 37 taken 228 times.
✓ Branch 31 → 32 taken 137 times.
✓ Branch 32 → 33 taken 137 times.
✓ Branch 33 → 34 taken 137 times.
|
502 | if (fresh) { component.name = QStringLiteral("VTODO"); component.setPropertyValue("UID", ICal::escapeText(task.uid)); } |
| 104 | 365 | bool changed = fresh; | |
| 105 | 365 | bool significant = false; | |
| 106 | 3068 | const auto text = [&](const QString &name, const QString &oldValue, const QString &value, bool escaped = true) { | |
| 107 |
6/6✓ Branch 2 → 3 taken 2060 times.
✓ Branch 2 → 6 taken 1008 times.
✓ Branch 4 → 5 taken 1886 times.
✓ Branch 4 → 6 taken 174 times.
✓ Branch 7 → 8 taken 1886 times.
✓ Branch 7 → 9 taken 1182 times.
|
3068 | if (!fresh && oldValue == value) return; |
| 108 |
2/2✓ Branch 10 → 11 taken 487 times.
✓ Branch 10 → 12 taken 695 times.
|
1182 | if (value.isEmpty()) component.removeProperties(name); |
| 109 |
6/6✓ Branch 13 → 14 taken 283 times.
✓ Branch 13 → 20 taken 412 times.
✓ Branch 14 → 15 taken 258 times.
✓ Branch 14 → 16 taken 25 times.
✓ Branch 15 → 17 taken 258 times.
✓ Branch 17 → 18 taken 283 times.
|
695 | else if (auto *existing = component.property(name)) existing->setValue(escaped ? ICal::escapeText(value) : value); |
| 110 |
4/4✓ Branch 20 → 21 taken 355 times.
✓ Branch 20 → 22 taken 57 times.
✓ Branch 21 → 23 taken 355 times.
✓ Branch 23 → 24 taken 412 times.
|
412 | else component.setPropertyValue(name, escaped ? ICal::escapeText(value) : value); |
| 111 | 1182 | changed = true; | |
| 112 | 365 | }; | |
| 113 |
2/2✓ Branch 37 → 38 taken 365 times.
✓ Branch 38 → 39 taken 365 times.
|
365 | text("SUMMARY", before.summary, task.summary); |
| 114 |
2/2✓ Branch 40 → 41 taken 365 times.
✓ Branch 41 → 42 taken 365 times.
|
365 | text("DESCRIPTION", before.description, task.description); |
| 115 |
2/2✓ Branch 43 → 44 taken 365 times.
✓ Branch 44 → 45 taken 365 times.
|
365 | text("X-MAILJD-MESSAGE-ID", before.relatedMessageId, task.relatedMessageId); |
| 116 |
2/2✓ Branch 46 → 47 taken 365 times.
✓ Branch 47 → 48 taken 365 times.
|
365 | text("UID", before.uid, task.uid); |
| 117 |
2/2✓ Branch 49 → 50 taken 365 times.
✓ Branch 50 → 51 taken 365 times.
|
365 | text("STATUS", before.status, task.status); |
| 118 | 365 | significant |= before.status != task.status; | |
| 119 |
8/8✓ Branch 53 → 54 taken 137 times.
✓ Branch 53 → 55 taken 228 times.
✓ Branch 54 → 55 taken 14 times.
✓ Branch 54 → 63 taken 123 times.
✓ Branch 55 → 56 taken 242 times.
✓ Branch 56 → 57 taken 242 times.
✓ Branch 57 → 58 taken 242 times.
✓ Branch 58 → 59 taken 242 times.
|
365 | if (!fresh || task.priority > 0) text("PRIORITY", QString::number(before.priority), QString::number(task.priority), false); |
| 120 |
8/8✓ Branch 63 → 64 taken 137 times.
✓ Branch 63 → 65 taken 228 times.
✓ Branch 64 → 65 taken 23 times.
✓ Branch 64 → 73 taken 114 times.
✓ Branch 65 → 66 taken 251 times.
✓ Branch 66 → 67 taken 251 times.
✓ Branch 67 → 68 taken 251 times.
✓ Branch 68 → 69 taken 251 times.
|
365 | if (!fresh || task.percentComplete > 0) text("PERCENT-COMPLETE", QString::number(before.percentComplete), QString::number(task.percentComplete), false); |
| 121 |
2/2✓ Branch 73 → 74 taken 365 times.
✓ Branch 74 → 75 taken 365 times.
|
365 | text("X-MAILJD-PREVIOUS-STATUS", before.previousStatus, task.previousStatus); |
| 122 |
2/2✓ Branch 76 → 77 taken 15 times.
✓ Branch 76 → 85 taken 350 times.
|
365 | if (before.previousPercent != task.previousPercent) |
| 123 |
3/3✓ Branch 77 → 78 taken 15 times.
✓ Branch 79 → 80 taken 15 times.
✓ Branch 80 → 81 taken 15 times.
|
15 | text("X-MAILJD-PREVIOUS-PERCENT", {}, QString::number(task.previousPercent), false); |
| 124 | 1232 | const auto date = [&](const QString &name, const QDateTime &oldStamp, bool oldDate, const QDateTime &stamp, bool dateOnly) { | |
| 125 |
6/6✓ Branch 2 → 3 taken 684 times.
✓ Branch 2 → 6 taken 548 times.
✓ Branch 4 → 5 taken 653 times.
✓ Branch 4 → 6 taken 31 times.
✓ Branch 7 → 8 taken 653 times.
✓ Branch 7 → 9 taken 579 times.
|
1232 | if (!fresh && sameDate(oldStamp, oldDate, stamp, dateOnly)) return; |
| 126 | 579 | writeDate(&component, name, stamp, dateOnly, resolver); changed = true; | |
| 127 |
6/6✓ Branch 12 → 13 taken 432 times.
✓ Branch 12 → 16 taken 147 times.
✓ Branch 15 → 16 taken 137 times.
✓ Branch 15 → 17 taken 295 times.
✓ Branch 18 → 19 taken 284 times.
✓ Branch 18 → 20 taken 295 times.
|
579 | if (name == QLatin1String("DUE") || name == QLatin1String("DTSTART")) significant = true; |
| 128 | 365 | }; | |
| 129 |
2/2✓ Branch 85 → 86 taken 365 times.
✓ Branch 86 → 87 taken 365 times.
|
365 | date("DUE", before.due, before.dueAllDay, task.due, task.dueAllDay); |
| 130 |
2/2✓ Branch 88 → 89 taken 365 times.
✓ Branch 89 → 90 taken 365 times.
|
365 | date("DTSTART", before.dtStart, before.startAllDay, task.dtStart, task.startAllDay); |
| 131 |
2/2✓ Branch 91 → 92 taken 365 times.
✓ Branch 92 → 93 taken 365 times.
|
365 | date("COMPLETED", before.completedAt, false, task.completedAt, false); |
| 132 |
8/8✓ Branch 94 → 95 taken 137 times.
✓ Branch 94 → 106 taken 228 times.
✓ Branch 95 → 96 taken 137 times.
✓ Branch 96 → 97 taken 17 times.
✓ Branch 96 → 98 taken 120 times.
✓ Branch 98 → 99 taken 120 times.
✓ Branch 100 → 101 taken 137 times.
✓ Branch 101 → 102 taken 137 times.
|
365 | if (fresh) date("CREATED", {}, false, task.created.isValid() ? task.created : QDateTime::currentDateTimeUtc(), false); |
| 133 |
2/2✓ Branch 106 → 107 taken 365 times.
✓ Branch 107 → 108 taken 365 times.
|
365 | text("RRULE", before.rrule, task.rrule, false); |
| 134 | 365 | significant |= before.rrule != task.rrule; | |
| 135 |
2/2✓ Branch 111 → 112 taken 6 times.
✓ Branch 111 → 169 taken 359 times.
|
365 | if (before.parentUid != task.parentUid) { |
| 136 | 6 | auto properties = component.properties; | |
| 137 |
1/1✓ Branch 113 → 114 taken 6 times.
|
6 | component.properties.clear(); |
| 138 |
4/4✓ Branch 114 → 115 taken 6 times.
✓ Branch 115 → 116 taken 6 times.
✓ Branch 147 → 117 taken 53 times.
✓ Branch 147 → 148 taken 6 times.
|
59 | for (const auto &property : properties) |
| 139 |
2/2✓ Branch 120 → 121 taken 1 time.
✓ Branch 120 → 131 taken 52 times.
|
54 | if (property.name != QLatin1String("RELATED-TO") || |
| 140 |
19/31✓ Branch 121 → 122 taken 1 time.
✓ Branch 122 → 123 taken 1 time.
✓ Branch 124 → 125 taken 1 time.
✗ Branch 124 → 132 not taken.
✓ Branch 126 → 127 taken 1 time.
✓ Branch 127 → 128 taken 1 time.
✓ Branch 128 → 129 taken 1 time.
✗ Branch 130 → 131 not taken.
✓ Branch 130 → 132 taken 1 time.
✓ Branch 133 → 134 taken 1 time.
✓ Branch 133 → 135 taken 52 times.
✓ Branch 135 → 136 taken 1 time.
✓ Branch 135 → 137 taken 52 times.
✓ Branch 137 → 138 taken 1 time.
✓ Branch 137 → 139 taken 52 times.
✓ Branch 139 → 140 taken 1 time.
✓ Branch 139 → 141 taken 52 times.
✓ Branch 141 → 142 taken 1 time.
✓ Branch 141 → 143 taken 52 times.
✓ Branch 143 → 144 taken 52 times.
✓ Branch 143 → 145 taken 1 time.
✗ Branch 481 → 482 not taken.
✗ Branch 481 → 483 not taken.
✗ Branch 485 → 486 not taken.
✗ Branch 485 → 487 not taken.
✗ Branch 489 → 490 not taken.
✗ Branch 489 → 491 not taken.
✗ Branch 494 → 495 not taken.
✗ Branch 494 → 496 not taken.
✗ Branch 498 → 499 not taken.
✗ Branch 498 → 500 not taken.
|
54 | (!property.parameter("RELTYPE").isEmpty() && property.parameter("RELTYPE").toUpper() != QLatin1String("PARENT"))) |
| 141 |
1/1✓ Branch 144 → 145 taken 52 times.
|
52 | component.properties << property; |
| 142 |
2/2✓ Branch 149 → 150 taken 5 times.
✓ Branch 149 → 167 taken 1 time.
|
6 | if (!task.parentUid.isEmpty()) { |
| 143 |
1/1✓ Branch 156 → 157 taken 5 times.
|
10 | ICal::Property parent; parent.name = QStringLiteral("RELATED-TO"); parent.value = ICal::escapeText(task.parentUid); |
| 144 |
4/4✓ Branch 159 → 160 taken 5 times.
✓ Branch 160 → 161 taken 5 times.
✓ Branch 161 → 162 taken 5 times.
✓ Branch 164 → 165 taken 5 times.
|
5 | parent.setParameter("RELTYPE", "PARENT"); component.appendProperty(parent); |
| 145 | 5 | } | |
| 146 | 6 | changed = true; | |
| 147 | 6 | } | |
| 148 |
3/3✓ Branch 169 → 170 taken 365 times.
✓ Branch 170 → 171 taken 2 times.
✓ Branch 170 → 194 taken 363 times.
|
365 | if (before.tags != task.tags) { |
| 149 |
2/2✓ Branch 171 → 172 taken 2 times.
✓ Branch 172 → 173 taken 2 times.
|
2 | component.removeProperties("CATEGORIES"); QStringList values; |
| 150 |
4/4✓ Branch 177 → 178 taken 2 times.
✓ Branch 178 → 179 taken 2 times.
✓ Branch 182 → 176 taken 2 times.
✓ Branch 182 → 183 taken 2 times.
|
4 | for (const auto &tag : task.tags) values << ICal::escapeText(tag); |
| 151 |
4/5✓ Branch 184 → 185 taken 2 times.
✗ Branch 184 → 192 not taken.
✓ Branch 186 → 187 taken 2 times.
✓ Branch 187 → 188 taken 2 times.
✓ Branch 188 → 189 taken 2 times.
|
2 | if (!values.isEmpty()) component.setPropertyValue("CATEGORIES", values.join(',')); |
| 152 | 2 | changed = true; | |
| 153 | 2 | } | |
| 154 |
5/5✓ Branch 194 → 195 taken 5 times.
✓ Branch 194 → 203 taken 360 times.
✓ Branch 195 → 196 taken 5 times.
✓ Branch 197 → 198 taken 5 times.
✓ Branch 198 → 199 taken 5 times.
|
365 | if (before.sortOrder != task.sortOrder) text("X-APPLE-SORT-ORDER", {}, QString::number(task.sortOrder), false); |
| 155 | // F-25 (SPRINT-104): an untouched relative reminder follows its anchor. | ||
| 156 | // When DUE or DTSTART changed and the task still carries the alarm | ||
| 157 | // times derived from the OLD anchor, re-derive them from the updated | ||
| 158 | // component: the relative trigger ("15 minutes before") keeps its | ||
| 159 | // meaning and stays relative, instead of being frozen as an absolute | ||
| 160 | // stamp on the old day (reproduced: due moved a week ahead, the alarm | ||
| 161 | // stayed at the old 08:45 and was written as TRIGGER;VALUE=DATE-TIME). | ||
| 162 | const bool anchorChanged = | ||
| 163 |
3/3✓ Branch 203 → 204 taken 365 times.
✓ Branch 204 → 205 taken 329 times.
✓ Branch 204 → 207 taken 36 times.
|
694 | !sameDate(before.due, before.dueAllDay, task.due, task.dueAllDay) || |
| 164 |
2/3✓ Branch 205 → 206 taken 329 times.
✗ Branch 206 → 207 not taken.
✓ Branch 206 → 208 taken 329 times.
|
329 | !sameDate(before.dtStart, before.startAllDay, task.dtStart, task.startAllDay); |
| 165 | const QList<QDateTime> alarms = | ||
| 166 |
3/3✓ Branch 210 → 211 taken 36 times.
✓ Branch 211 → 212 taken 32 times.
✓ Branch 211 → 214 taken 4 times.
|
36 | (anchorChanged && task.alarmTimes == before.alarmTimes) |
| 167 |
3/5✓ Branch 212 → 213 taken 32 times.
✓ Branch 215 → 216 taken 32 times.
✓ Branch 215 → 217 taken 333 times.
✗ Branch 543 → 544 not taken.
✗ Branch 543 → 545 not taken.
|
397 | ? taskFromComponent(component, resolver).alarmTimes |
| 168 |
2/2✓ Branch 209 → 210 taken 36 times.
✓ Branch 209 → 214 taken 329 times.
|
401 | : task.alarmTimes; |
| 169 |
4/4✓ Branch 217 → 218 taken 365 times.
✓ Branch 218 → 219 taken 365 times.
✓ Branch 220 → 221 taken 4 times.
✓ Branch 220 → 298 taken 361 times.
|
365 | if (taskFromComponent(component, resolver).alarmTimes != alarms) { |
| 170 | 4 | QList<ICal::Component> kept; | |
| 171 |
3/4✓ Branch 221 → 222 taken 4 times.
✓ Branch 222 → 223 taken 4 times.
✗ Branch 252 → 224 not taken.
✓ Branch 252 → 253 taken 4 times.
|
4 | for (const auto &child : component.components) |
| 172 | ✗ | if (child.name != QLatin1String("VALARM") || !QStringList{"DISPLAY", "AUDIO", ""}.contains(child.value("ACTION"))) kept << child; | |
| 173 | 4 | component.components = kept; | |
| 174 |
2/2✓ Branch 295 → 256 taken 5 times.
✓ Branch 295 → 296 taken 4 times.
|
9 | for (const auto &stamp : alarms) { |
| 175 | 10 | ICal::Component alarm; alarm.name = QStringLiteral("VALARM"); | |
| 176 |
6/6✓ Branch 263 → 264 taken 5 times.
✓ Branch 264 → 265 taken 5 times.
✓ Branch 265 → 266 taken 5 times.
✓ Branch 268 → 269 taken 5 times.
✓ Branch 269 → 270 taken 5 times.
✓ Branch 270 → 271 taken 5 times.
|
5 | alarm.setPropertyValue("ACTION", "DISPLAY"); alarm.setPropertyValue("DESCRIPTION", ICal::escapeText(task.summary)); |
| 177 |
3/3✓ Branch 279 → 280 taken 5 times.
✓ Branch 280 → 281 taken 5 times.
✓ Branch 281 → 282 taken 5 times.
|
10 | ICal::Property trigger; trigger.name = QStringLiteral("TRIGGER"); trigger.setParameter("VALUE", "DATE-TIME"); |
| 178 |
3/3✓ Branch 284 → 285 taken 5 times.
✓ Branch 285 → 286 taken 5 times.
✓ Branch 289 → 290 taken 5 times.
|
5 | trigger.value = ICalTime::formatValue(stamp.toUTC(), false); alarm.appendProperty(trigger); |
| 179 |
1/1✓ Branch 290 → 291 taken 5 times.
|
5 | component.components << alarm; |
| 180 | 5 | } | |
| 181 | 4 | changed = true; | |
| 182 | 4 | } | |
| 183 |
10/12✓ Branch 298 → 299 taken 99 times.
✓ Branch 298 → 302 taken 266 times.
✓ Branch 299 → 300 taken 99 times.
✓ Branch 300 → 301 taken 99 times.
✓ Branch 301 → 302 taken 8 times.
✓ Branch 301 → 303 taken 91 times.
✓ Branch 304 → 305 taken 99 times.
✓ Branch 304 → 306 taken 266 times.
✓ Branch 306 → 307 taken 274 times.
✓ Branch 306 → 336 taken 91 times.
✗ Branch 607 → 608 not taken.
✗ Branch 607 → 609 not taken.
|
365 | if (changed || !component.hasProperty("DTSTAMP")) { |
| 184 |
2/2✓ Branch 307 → 308 taken 274 times.
✓ Branch 308 → 309 taken 274 times.
|
274 | const QString now = ICalTime::formatValue(QDateTime::currentDateTimeUtc(), false); |
| 185 |
4/4✓ Branch 310 → 311 taken 274 times.
✓ Branch 311 → 312 taken 274 times.
✓ Branch 313 → 314 taken 274 times.
✓ Branch 314 → 315 taken 274 times.
|
274 | component.setPropertyValue("DTSTAMP", now); component.setPropertyValue("LAST-MODIFIED", now); |
| 186 |
16/20✓ Branch 316 → 317 taken 137 times.
✓ Branch 316 → 318 taken 137 times.
✓ Branch 317 → 318 taken 33 times.
✓ Branch 317 → 334 taken 104 times.
✓ Branch 318 → 319 taken 137 times.
✓ Branch 318 → 320 taken 33 times.
✓ Branch 320 → 321 taken 33 times.
✓ Branch 321 → 322 taken 33 times.
✓ Branch 322 → 323 taken 33 times.
✓ Branch 324 → 325 taken 170 times.
✓ Branch 325 → 326 taken 170 times.
✓ Branch 326 → 327 taken 170 times.
✓ Branch 329 → 330 taken 33 times.
✓ Branch 329 → 331 taken 137 times.
✓ Branch 331 → 332 taken 33 times.
✓ Branch 331 → 333 taken 137 times.
✗ Branch 625 → 626 not taken.
✗ Branch 625 → 627 not taken.
✗ Branch 629 → 630 not taken.
✗ Branch 629 → 631 not taken.
|
274 | if (fresh || significant) component.setPropertyValue("SEQUENCE", QString::number(fresh ? 0 : component.value("SEQUENCE").toInt() + 1)); |
| 187 | 274 | } | |
| 188 | 365 | return component; | |
| 189 | 365 | } | |
| 190 | |||
| 191 | 366 | QByteArray buildResource(const CalendarTask &task) { | |
| 192 | 366 | ICal::Component calendar; | |
| 193 |
2/2✓ Branch 3 → 4 taken 180 times.
✓ Branch 3 → 44 taken 186 times.
|
366 | if (!task.resourceIcal.isEmpty()) { |
| 194 | // S106-148 (Sprint 97 writer guard): lines the parser skipped would be | ||
| 195 | // missing from the rewritten resource and so deleted on the server. | ||
| 196 | 180 | QList<ICal::Component> parsed; | |
| 197 | 180 | int skipped = 0; | |
| 198 |
2/3✓ Branch 4 → 5 taken 180 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 180 times.
|
180 | if (!ICal::parse(task.resourceIcal, &parsed, nullptr, &skipped)) return {}; |
| 199 |
2/2✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 23 taken 179 times.
|
180 | if (skipped > 0) { |
| 200 |
7/7✓ Branch 9 → 10 taken 1 time.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 14 → 15 taken 1 time.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 20 → 11 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
|
2 | qCWarning(lcTodoCodec) << "Task resource has" << skipped << "unreadable lines; not rewritten"; |
| 201 | 1 | return {}; | |
| 202 | } | ||
| 203 |
3/4✓ Branch 23 → 24 taken 179 times.
✓ Branch 24 → 25 taken 179 times.
✓ Branch 33 → 26 taken 179 times.
✗ Branch 33 → 34 not taken.
|
179 | for (const auto &component : parsed) |
| 204 |
1/2✓ Branch 29 → 30 taken 179 times.
✗ Branch 29 → 31 not taken.
|
179 | if (component.name == QLatin1String("VCALENDAR")) { calendar = component; break; } |
| 205 |
1/2✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 179 times.
|
179 | if (calendar.name.isEmpty()) return {}; |
| 206 | 180 | } | |
| 207 |
2/2✓ Branch 45 → 46 taken 186 times.
✓ Branch 45 → 63 taken 179 times.
|
365 | if (calendar.name.isEmpty()) { |
| 208 |
3/3✓ Branch 52 → 53 taken 186 times.
✓ Branch 53 → 54 taken 186 times.
✓ Branch 54 → 55 taken 186 times.
|
186 | calendar.name = QStringLiteral("VCALENDAR"); calendar.setPropertyValue("VERSION", "2.0"); |
| 209 |
3/3✓ Branch 57 → 58 taken 186 times.
✓ Branch 58 → 59 taken 186 times.
✓ Branch 59 → 60 taken 186 times.
|
186 | calendar.setPropertyValue("PRODID", "-//MailJD//CalDAV Client//EN"); |
| 210 | } | ||
| 211 |
1/1✓ Branch 63 → 64 taken 365 times.
|
365 | const ICalTime::ZoneResolver resolver(calendar); |
| 212 |
1/1✓ Branch 64 → 65 taken 365 times.
|
365 | const auto todo = taskComponent(task, resolver); |
| 213 |
1/2✗ Branch 66 → 67 not taken.
✓ Branch 66 → 68 taken 365 times.
|
365 | if (todo.name.isEmpty()) return {}; |
| 214 | 365 | bool replaced = false; | |
| 215 | // S106-959: compare the UID the way the parser derived task.uid (unescaped, | ||
| 216 | // trimmed); the raw escaped text never matched a UID with , ; \ or a line | ||
| 217 | // break, and every save appended another master VTODO. | ||
| 218 |
4/4✓ Branch 68 → 69 taken 365 times.
✓ Branch 69 → 70 taken 365 times.
✓ Branch 101 → 71 taken 180 times.
✓ Branch 101 → 102 taken 186 times.
|
366 | for (auto &child : calendar.components) |
| 219 |
12/24✓ Branch 74 → 75 taken 180 times.
✗ Branch 74 → 85 not taken.
✓ Branch 75 → 76 taken 180 times.
✓ Branch 76 → 77 taken 180 times.
✓ Branch 77 → 78 taken 180 times.
✓ Branch 78 → 79 taken 180 times.
✓ Branch 80 → 81 taken 179 times.
✓ Branch 80 → 85 taken 1 time.
✓ Branch 90 → 91 taken 180 times.
✗ Branch 90 → 92 not taken.
✓ Branch 92 → 93 taken 180 times.
✗ Branch 92 → 94 not taken.
✓ Branch 94 → 95 taken 180 times.
✗ Branch 94 → 96 not taken.
✓ Branch 96 → 97 taken 179 times.
✓ Branch 96 → 99 taken 1 time.
✗ Branch 209 → 210 not taken.
✗ Branch 209 → 211 not taken.
✗ Branch 213 → 214 not taken.
✗ Branch 213 → 215 not taken.
✗ Branch 217 → 218 not taken.
✗ Branch 217 → 219 not taken.
✗ Branch 221 → 222 not taken.
✗ Branch 221 → 223 not taken.
|
539 | if (child.name == QLatin1String("VTODO") && ICal::unescapeText(child.value("UID")).trimmed() == task.uid && |
| 220 |
6/10✓ Branch 81 → 82 taken 179 times.
✓ Branch 82 → 83 taken 179 times.
✓ Branch 83 → 84 taken 179 times.
✗ Branch 83 → 85 not taken.
✓ Branch 86 → 87 taken 179 times.
✓ Branch 86 → 88 taken 1 time.
✓ Branch 88 → 89 taken 180 times.
✗ Branch 88 → 90 not taken.
✗ Branch 205 → 206 not taken.
✗ Branch 205 → 207 not taken.
|
359 | !child.hasProperty("RECURRENCE-ID")) { |
| 221 | 179 | child = todo; replaced = true; break; | |
| 222 | } | ||
| 223 |
3/3✓ Branch 102 → 103 taken 186 times.
✓ Branch 102 → 104 taken 179 times.
✓ Branch 103 → 104 taken 186 times.
|
365 | if (!replaced) calendar.components << todo; |
| 224 |
2/2✓ Branch 104 → 105 taken 365 times.
✓ Branch 105 → 106 taken 365 times.
|
365 | calendar.removeProperties("METHOD"); |
| 225 | 365 | QSet<QString> defined; | |
| 226 |
5/10✓ Branch 108 → 109 taken 365 times.
✓ Branch 109 → 110 taken 365 times.
✓ Branch 111 → 112 taken 365 times.
✓ Branch 112 → 113 taken 365 times.
✗ Branch 115 → 116 not taken.
✗ Branch 116 → 117 not taken.
✗ Branch 117 → 118 not taken.
✗ Branch 118 → 119 not taken.
✗ Branch 124 → 114 not taken.
✓ Branch 124 → 125 taken 365 times.
|
365 | for (const auto &zone : calendar.componentsNamed("VTIMEZONE")) defined.insert(ICal::unescapeText(zone.value("TZID"))); |
| 227 |
2/2✓ Branch 172 → 128 taken 3575 times.
✓ Branch 172 → 173 taken 365 times.
|
3940 | for (const auto &property : todo.properties) { |
| 228 |
2/2✓ Branch 129 → 130 taken 3575 times.
✓ Branch 130 → 131 taken 3575 times.
|
3575 | const QString tzid = property.parameter("TZID"); |
| 229 |
6/6✓ Branch 133 → 134 taken 79 times.
✓ Branch 133 → 136 taken 3496 times.
✓ Branch 135 → 136 taken 19 times.
✓ Branch 135 → 137 taken 60 times.
✓ Branch 138 → 139 taken 3515 times.
✓ Branch 138 → 140 taken 60 times.
|
3575 | if (tzid.isEmpty() || defined.contains(tzid)) continue; |
| 230 |
1/1✓ Branch 140 → 141 taken 60 times.
|
60 | const auto zone = resolver.resolve(tzid); |
| 231 |
2/3✓ Branch 141 → 142 taken 60 times.
✗ Branch 142 → 143 not taken.
✓ Branch 142 → 145 taken 60 times.
|
60 | if (!zone.isValid()) return {}; |
| 232 |
5/7✓ Branch 145 → 146 taken 60 times.
✓ Branch 146 → 147 taken 60 times.
✗ Branch 146 → 148 not taken.
✓ Branch 147 → 149 taken 60 times.
✗ Branch 148 → 149 not taken.
✓ Branch 149 → 150 taken 60 times.
✓ Branch 150 → 151 taken 60 times.
|
60 | auto definition = ICalTime::vtimezoneFor(zone, (task.due.isValid() ? task.due.date() : QDate::currentDate()).year()); |
| 233 |
5/5✓ Branch 151 → 152 taken 60 times.
✓ Branch 152 → 153 taken 60 times.
✓ Branch 153 → 154 taken 60 times.
✓ Branch 156 → 157 taken 60 times.
✓ Branch 157 → 158 taken 60 times.
|
60 | definition.setPropertyValue("TZID", ICal::escapeText(tzid)); calendar.components.prepend(definition); defined.insert(tzid); |
| 234 | 3575 | } | |
| 235 |
2/2✓ Branch 173 → 174 taken 365 times.
✓ Branch 174 → 175 taken 365 times.
|
365 | return ICal::serialize(calendar).toUtf8(); |
| 236 | 366 | } | |
| 237 | |||
| 238 | 171 | void adoptPushedResource(CalendarTask *task, const QByteArray &body) { | |
| 239 | 171 | Resource resource; | |
| 240 |
6/12✓ Branch 2 → 3 taken 171 times.
✗ Branch 2 → 6 not taken.
✓ Branch 3 → 4 taken 171 times.
✓ Branch 4 → 5 taken 171 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 171 times.
✓ Branch 8 → 9 taken 171 times.
✗ Branch 8 → 10 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 171 times.
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 48 not taken.
|
171 | if (!task || !parseResource(QString::fromUtf8(body), &resource)) return; |
| 241 |
3/4✓ Branch 12 → 13 taken 171 times.
✓ Branch 13 → 14 taken 171 times.
✓ Branch 38 → 15 taken 171 times.
✗ Branch 38 → 39 not taken.
|
171 | for (const auto &candidate : resource.tasks) |
| 242 |
10/22✓ Branch 17 → 18 taken 171 times.
✗ Branch 17 → 24 not taken.
✓ Branch 18 → 19 taken 171 times.
✓ Branch 19 → 20 taken 171 times.
✓ Branch 20 → 21 taken 171 times.
✓ Branch 21 → 22 taken 171 times.
✓ Branch 22 → 23 taken 171 times.
✗ Branch 22 → 24 not taken.
✓ Branch 25 → 26 taken 171 times.
✗ Branch 25 → 27 not taken.
✓ Branch 27 → 28 taken 171 times.
✗ Branch 27 → 29 not taken.
✓ Branch 29 → 30 taken 171 times.
✗ Branch 29 → 31 not taken.
✓ Branch 31 → 32 taken 171 times.
✗ Branch 31 → 36 not taken.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 52 not taken.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 56 not taken.
✗ Branch 58 → 59 not taken.
✗ Branch 58 → 60 not taken.
|
171 | if (candidate.uid == task->uid && !ICal::parseFirst(candidate.icalRaw, "VTODO").hasProperty("RECURRENCE-ID")) { |
| 243 | 171 | task->icalRaw = candidate.icalRaw; task->resourceIcal = candidate.resourceIcal; | |
| 244 | // S106-133: the reminder times derive from the pushed component. A | ||
| 245 | // stale list (from before the anchor moved) would read as a manual | ||
| 246 | // reminder edit on the next save and freeze the relative trigger as | ||
| 247 | // an absolute stamp on the old day. | ||
| 248 | 171 | task->alarmTimes = candidate.alarmTimes; | |
| 249 | 171 | return; | |
| 250 | } | ||
| 251 | 171 | } | |
| 252 | } | ||
| 253 |