MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 97.8% 88 / 0 / 90
Functions: 100.0% 4 / 0 / 4
Branches: 84.4% 189 / 0 / 224

presentation/QuickContactMenu.cpp
Line Branch Exec Source
1 #include "QuickContactMenu.h"
2
3 #include "util/MenuText.h"
4
5 #include <QApplication>
6 #include <QIcon>
7 #include <QLoggingCategory>
8 #include <QMenu>
9 #include <QWindow>
10
11
4/7
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 8 taken 3 times.
✓ 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.
5 Q_LOGGING_CATEGORY(lcContactMenu, "mailjd.contacts.menu")
12
13 10 bool QuickContactMenu::show(const QVariantMap &context, QObject *window, qreal x, qreal y) {
14 10 auto *parent = qobject_cast<QWindow *>(window);
15
6/7
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 7 taken 1 time.
✓ Branch 5 → 6 taken 9 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 9 times.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 11 taken 9 times.
10 if (!parent || !qobject_cast<QApplication *>(QCoreApplication::instance()))
16 1 return false;
17
3/6
✓ Branch 11 → 12 taken 9 times.
✓ Branch 12 → 13 taken 9 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 9 times.
✗ Branch 678 → 679 not taken.
✗ Branch 678 → 680 not taken.
9 auto *menu = new QMenu;
18
1/1
✓ Branch 18 → 19 taken 9 times.
18 menu->setObjectName(QStringLiteral("nativeContactMenu"));
19
1/1
✓ Branch 21 → 22 taken 9 times.
9 menu->setAttribute(Qt::WA_DeleteOnClose);
20 111 const auto add = [this](QMenu *target, const QString &icon, const QString &label, const QString &action,
21 const QVariantMap &fields = {}) {
22 // S106-280: addresses, book and group names are shown as written.
23
3/3
✓ Branch 2 → 3 taken 111 times.
✓ Branch 3 → 4 taken 111 times.
✓ Branch 4 → 5 taken 111 times.
111 auto *entry = target->addAction(QIcon::fromTheme(icon), MenuText::plain(label));
24
2/2
✓ Branch 10 → 11 taken 111 times.
✓ Branch 11 → 12 taken 111 times.
222 entry->setObjectName(QStringLiteral("contactMenu-") + action);
25
1/3
✓ Branch 17 → 18 taken 111 times.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 41 not taken.
111 connect(entry, &QAction::triggered, this, [this, action, fields] {
26
6/6
✓ Branch 2 → 3 taken 5 times.
✓ Branch 6 → 7 taken 5 times.
✓ Branch 7 → 8 taken 5 times.
✓ Branch 8 → 9 taken 5 times.
✓ Branch 12 → 4 taken 5 times.
✓ Branch 12 → 13 taken 5 times.
10 qCDebug(lcContactMenu) << "Menu action" << action;
27 5 emit actionRequested(action, fields);
28 5 });
29 111 return entry;
30 9 };
31
2/2
✓ Branch 26 → 27 taken 9 times.
✓ Branch 27 → 28 taken 9 times.
18 const int count = context.value(QStringLiteral("count")).toInt();
32
2/2
✓ Branch 36 → 37 taken 9 times.
✓ Branch 37 → 38 taken 9 times.
18 const bool writable = context.value(QStringLiteral("writable")).toBool();
33
2/2
✓ Branch 46 → 47 taken 9 times.
✓ Branch 47 → 48 taken 9 times.
18 const bool collected = context.value(QStringLiteral("collected")).toBool();
34
2/2
✓ Branch 56 → 57 taken 9 times.
✓ Branch 57 → 58 taken 9 times.
18 const QStringList addresses = context.value(QStringLiteral("addresses")).toStringList();
35
2/2
✓ Branch 66 → 67 taken 9 times.
✓ Branch 67 → 68 taken 9 times.
18 const qint64 currentBook = context.value(QStringLiteral("bookId")).toLongLong();
36
2/2
✓ Branch 76 → 77 taken 9 times.
✓ Branch 77 → 78 taken 9 times.
18 const QVariantList books = context.value(QStringLiteral("books")).toList();
37
38 // F103-30: opened on a node of the relationship graph — its own entries first.
39
18/26
✓ Branch 82 → 83 taken 8 times.
✓ Branch 82 → 92 taken 1 time.
✓ Branch 83 → 84 taken 7 times.
✓ Branch 83 → 92 taken 1 time.
✓ Branch 88 → 89 taken 7 times.
✓ Branch 89 → 90 taken 7 times.
✓ Branch 90 → 91 taken 2 times.
✓ Branch 90 → 92 taken 5 times.
✓ Branch 93 → 94 taken 7 times.
✓ Branch 93 → 95 taken 2 times.
✓ Branch 95 → 96 taken 7 times.
✓ Branch 95 → 97 taken 2 times.
✓ Branch 97 → 98 taken 7 times.
✓ Branch 97 → 99 taken 2 times.
✓ Branch 99 → 100 taken 7 times.
✓ Branch 99 → 101 taken 2 times.
✓ Branch 101 → 102 taken 2 times.
✓ Branch 101 → 185 taken 7 times.
✗ Branch 759 → 760 not taken.
✗ Branch 759 → 761 not taken.
✗ Branch 763 → 764 not taken.
✗ Branch 763 → 765 not taken.
✗ Branch 767 → 768 not taken.
✗ Branch 767 → 769 not taken.
✗ Branch 771 → 772 not taken.
✗ Branch 771 → 773 not taken.
16 if (count == 1 && !collected && context.value(QStringLiteral("graph")).toBool()) {
40
1/1
✓ Branch 106 → 107 taken 2 times.
8 add(menu, QStringLiteral("format-justify-center"), tr("Put in the middle"), QStringLiteral("graphCenter"))
41
4/4
✓ Branch 110 → 111 taken 2 times.
✓ Branch 115 → 116 taken 2 times.
✓ Branch 116 → 117 taken 2 times.
✓ Branch 117 → 118 taken 2 times.
4 ->setEnabled(!context.value(QStringLiteral("center")).toBool());
42
1/1
✓ Branch 132 → 133 taken 2 times.
8 add(menu, QStringLiteral("draw-path"), tr("How do I know them?"), QStringLiteral("graphHow"))
43
4/4
✓ Branch 136 → 137 taken 2 times.
✓ Branch 141 → 142 taken 2 times.
✓ Branch 142 → 143 taken 2 times.
✓ Branch 143 → 144 taken 2 times.
4 ->setEnabled(!context.value(QStringLiteral("isMe")).toBool());
44
2/2
✓ Branch 158 → 159 taken 2 times.
✓ Branch 162 → 163 taken 2 times.
6 add(menu, QStringLiteral("find-location"), tr("Show on world map"), QStringLiteral("graphMap"));
45
2/2
✓ Branch 173 → 174 taken 2 times.
✓ Branch 177 → 178 taken 2 times.
6 add(menu, QStringLiteral("list-add-user"), tr("Add relationship…"), QStringLiteral("relate"));
46
1/1
✓ Branch 184 → 185 taken 2 times.
2 menu->addSeparator();
47 }
48
5/6
✓ Branch 186 → 187 taken 3 times.
✓ Branch 186 → 189 taken 6 times.
✓ Branch 187 → 188 taken 3 times.
✗ Branch 187 → 189 not taken.
✓ Branch 190 → 191 taken 3 times.
✓ Branch 190 → 227 taken 6 times.
9 if (addresses.size() > 1 && count == 1) {
49
3/3
✓ Branch 191 → 192 taken 3 times.
✓ Branch 195 → 196 taken 3 times.
✓ Branch 196 → 197 taken 3 times.
6 QMenu *write = menu->addMenu(QIcon::fromTheme(QStringLiteral("mail-message-new")), tr("Write mail"));
50
2/2
✓ Branch 225 → 203 taken 6 times.
✓ Branch 225 → 226 taken 3 times.
9 for (const QString &address : addresses)
51
3/5
✓ Branch 213 → 214 taken 6 times.
✓ Branch 219 → 220 taken 6 times.
✓ Branch 219 → 221 taken 6 times.
✗ Branch 895 → 896 not taken.
✗ Branch 895 → 897 not taken.
18 add(write, {}, address, QStringLiteral("write"), {{QStringLiteral("address"), address}});
52 } else {
53
2/2
✓ Branch 231 → 232 taken 6 times.
✓ Branch 235 → 236 taken 6 times.
18 add(menu, QStringLiteral("mail-message-new"), tr("Write mail"), QStringLiteral("write"));
54 }
55
2/2
✓ Branch 243 → 244 taken 1 time.
✓ Branch 243 → 333 taken 8 times.
9 if (collected) {
56 // A collected address (D-4): keep it as a contact or forget it.
57
3/3
✓ Branch 244 → 245 taken 1 time.
✓ Branch 248 → 249 taken 1 time.
✓ Branch 249 → 250 taken 1 time.
2 QMenu *target = menu->addMenu(QIcon::fromTheme(QStringLiteral("contact-new")), tr("Add to address book"));
58
2/2
✓ Branch 300 → 256 taken 1 time.
✓ Branch 300 → 301 taken 1 time.
2 for (const QVariant &value : books) {
59
1/1
✓ Branch 257 → 258 taken 1 time.
1 const QVariantMap book = value.toMap();
60
5/7
✓ Branch 275 → 276 taken 1 time.
✓ Branch 276 → 277 taken 1 time.
✓ Branch 278 → 279 taken 1 time.
✓ Branch 289 → 290 taken 1 time.
✓ Branch 289 → 291 taken 1 time.
✗ Branch 969 → 970 not taken.
✗ Branch 969 → 971 not taken.
3 add(target, {}, book.value(QStringLiteral("name")).toString(), QStringLiteral("addToBook"),
61
1/1
✓ Branch 265 → 266 taken 1 time.
3 {{QStringLiteral("bookId"), book.value(QStringLiteral("bookId"))}});
62 1 }
63
2/2
✓ Branch 305 → 306 taken 1 time.
✓ Branch 309 → 310 taken 1 time.
3 add(menu, QStringLiteral("edit-copy"), tr("Copy address"), QStringLiteral("copyAddress"));
64
1/1
✓ Branch 316 → 317 taken 1 time.
1 menu->addSeparator();
65
2/2
✓ Branch 321 → 322 taken 1 time.
✓ Branch 325 → 326 taken 1 time.
3 add(menu, QStringLiteral("edit-clear-history"), tr("Forget"), QStringLiteral("forget"));
66 } else {
67
2/2
✓ Branch 333 → 334 taken 7 times.
✓ Branch 333 → 458 taken 1 time.
8 if (count == 1) {
68 // Sprint 107 S107.5.8: a conflicting card offers the resolver first.
69
3/4
✓ Branch 338 → 339 taken 7 times.
✓ Branch 339 → 340 taken 7 times.
✗ Branch 344 → 345 not taken.
✓ Branch 344 → 361 taken 7 times.
14 if (context.value(QStringLiteral("conflict")).toBool()) {
70 ✗ add(menu, QStringLiteral("dialog-warning"), tr("Resolve conflict…"), QStringLiteral("resolve"));
71 ✗ menu->addSeparator();
72 }
73
2/2
✓ Branch 365 → 366 taken 7 times.
✓ Branch 369 → 370 taken 7 times.
21 add(menu, QStringLiteral("document-open"), tr("Open"), QStringLiteral("open"));
74
3/3
✓ Branch 380 → 381 taken 7 times.
✓ Branch 384 → 385 taken 7 times.
✓ Branch 385 → 386 taken 7 times.
21 add(menu, QStringLiteral("document-edit"), tr("Edit"), QStringLiteral("edit"))->setEnabled(writable);
75
1/1
✓ Branch 396 → 397 taken 7 times.
28 add(menu, QStringLiteral("edit-copy"), tr("Copy address"), QStringLiteral("copyAddress"))
76
2/2
✓ Branch 400 → 401 taken 7 times.
✓ Branch 402 → 403 taken 7 times.
7 ->setEnabled(!addresses.isEmpty());
77
2/2
✓ Branch 413 → 414 taken 7 times.
✓ Branch 417 → 418 taken 7 times.
21 add(menu, QStringLiteral("edit-copy"), tr("Copy as vCard text"), QStringLiteral("copyVcard"));
78 // Sprint 103 D-6, F103-29: the card that is the user (per profile) —
79 // one checkable entry, ticked on the user's own card (unticking clears it).
80
2/2
✓ Branch 428 → 429 taken 7 times.
✓ Branch 429 → 430 taken 7 times.
14 const bool isMe = context.value(QStringLiteral("isMe")).toBool();
81
2/2
✓ Branch 442 → 443 taken 7 times.
✓ Branch 446 → 447 taken 7 times.
21 QAction *me = add(menu, QStringLiteral("user-identity"), tr("This is me"),
82
6/10
✓ Branch 435 → 436 taken 1 time.
✓ Branch 435 → 439 taken 6 times.
✓ Branch 451 → 452 taken 6 times.
✓ Branch 451 → 453 taken 1 time.
✓ Branch 453 → 454 taken 1 time.
✓ Branch 453 → 455 taken 6 times.
✗ Branch 1162 → 1163 not taken.
✗ Branch 1162 → 1164 not taken.
✗ Branch 1166 → 1167 not taken.
✗ Branch 1166 → 1168 not taken.
21 isMe ? QStringLiteral("notMe") : QStringLiteral("me"));
83
1/1
✓ Branch 456 → 457 taken 7 times.
7 me->setCheckable(true);
84
1/1
✓ Branch 457 → 458 taken 7 times.
7 me->setChecked(isMe);
85 }
86
1/1
✓ Branch 458 → 459 taken 8 times.
8 menu->addSeparator();
87
3/3
✓ Branch 459 → 460 taken 8 times.
✓ Branch 463 → 464 taken 8 times.
✓ Branch 464 → 465 taken 8 times.
16 QMenu *move = menu->addMenu(QIcon::fromTheme(QStringLiteral("go-jump")), tr("Move to"));
88
1/1
✓ Branch 469 → 470 taken 8 times.
8 move->setEnabled(writable);
89
2/2
✓ Branch 533 → 472 taken 13 times.
✓ Branch 533 → 534 taken 8 times.
21 for (const QVariant &value : books) {
90
1/1
✓ Branch 473 → 474 taken 13 times.
13 const QVariantMap book = value.toMap();
91
4/4
✓ Branch 478 → 479 taken 13 times.
✓ Branch 479 → 480 taken 13 times.
✓ Branch 484 → 485 taken 5 times.
✓ Branch 484 → 486 taken 8 times.
26 if (book.value(QStringLiteral("bookId")).toLongLong() == currentBook)
92 5 continue;
93
5/7
✓ Branch 503 → 504 taken 8 times.
✓ Branch 504 → 505 taken 8 times.
✓ Branch 506 → 507 taken 8 times.
✓ Branch 517 → 518 taken 8 times.
✓ Branch 517 → 519 taken 8 times.
✗ Branch 1225 → 1226 not taken.
✗ Branch 1225 → 1227 not taken.
24 add(move, {}, book.value(QStringLiteral("name")).toString(), QStringLiteral("move"),
94
1/1
✓ Branch 493 → 494 taken 8 times.
24 {{QStringLiteral("bookId"), book.value(QStringLiteral("bookId"))}});
95 13 }
96
3/3
✓ Branch 534 → 535 taken 8 times.
✓ Branch 538 → 539 taken 8 times.
✓ Branch 539 → 540 taken 8 times.
16 QMenu *group = menu->addMenu(QIcon::fromTheme(QStringLiteral("user-group-new")), tr("Add to group"));
97
1/1
✓ Branch 544 → 545 taken 8 times.
8 group->setEnabled(writable);
98
6/6
✓ Branch 549 → 550 taken 8 times.
✓ Branch 550 → 551 taken 8 times.
✓ Branch 555 → 556 taken 8 times.
✓ Branch 556 → 557 taken 8 times.
✓ Branch 580 → 558 taken 12 times.
✓ Branch 580 → 581 taken 8 times.
28 for (const QString &name : context.value(QStringLiteral("groups")).toStringList())
99
3/5
✓ Branch 568 → 569 taken 12 times.
✓ Branch 574 → 575 taken 12 times.
✓ Branch 574 → 576 taken 12 times.
✗ Branch 1293 → 1294 not taken.
✗ Branch 1293 → 1295 not taken.
44 add(group, {}, name, QStringLiteral("addGroup"), {{QStringLiteral("group"), name}});
100
1/1
✓ Branch 582 → 583 taken 8 times.
8 group->addSeparator();
101
2/2
✓ Branch 587 → 588 taken 8 times.
✓ Branch 591 → 592 taken 8 times.
24 add(group, QStringLiteral("list-add"), tr("New group…"), QStringLiteral("newGroup"));
102 // F100-15: two or more contacts can be merged (the dialog checks the book).
103
2/2
✓ Branch 598 → 599 taken 1 time.
✓ Branch 598 → 616 taken 7 times.
8 if (count > 1)
104
3/3
✓ Branch 603 → 604 taken 1 time.
✓ Branch 607 → 608 taken 1 time.
✓ Branch 608 → 609 taken 1 time.
3 add(menu, QStringLiteral("merge"), tr("Merge %n contacts…", "", count), QStringLiteral("merge"))->setEnabled(writable);
105
2/2
✓ Branch 620 → 621 taken 8 times.
✓ Branch 624 → 625 taken 8 times.
24 add(menu, QStringLiteral("document-export"), tr("Export as .vcf"), QStringLiteral("export"));
106
2/2
✓ Branch 635 → 636 taken 8 times.
✓ Branch 639 → 640 taken 8 times.
24 add(menu, QStringLiteral("mail-attachment"), tr("Send as vCard"), QStringLiteral("sendVcard"));
107
1/1
✓ Branch 646 → 647 taken 8 times.
8 menu->addSeparator();
108
4/4
✓ Branch 651 → 652 taken 1 time.
✓ Branch 651 → 653 taken 7 times.
✓ Branch 652 → 654 taken 1 time.
✓ Branch 653 → 654 taken 7 times.
40 add(menu, QStringLiteral("edit-delete"), count > 1 ? tr("Delete %n contacts", "", count) : tr("Delete"),
109 16 QStringLiteral("delete"))
110
2/2
✓ Branch 657 → 658 taken 8 times.
✓ Branch 658 → 659 taken 8 times.
8 ->setEnabled(writable);
111 }
112
1/1
✓ Branch 666 → 667 taken 9 times.
9 menu->winId();
113
2/3
✓ Branch 667 → 668 taken 9 times.
✓ Branch 668 → 669 taken 9 times.
✗ Branch 668 → 670 not taken.
9 if (auto *handle = menu->windowHandle())
114
1/1
✓ Branch 669 → 670 taken 9 times.
9 handle->setTransientParent(parent);
115
2/2
✓ Branch 671 → 672 taken 9 times.
✓ Branch 673 → 674 taken 9 times.
9 menu->popup(parent->mapToGlobal(QPointF(x, y)).toPoint());
116 9 return true;
117 63 }
118