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: 92.2% 165 / 0 / 179
Functions: 84.6% 11 / 0 / 13
Branches: 84.0% 236 / 0 / 281

data/RelationGraphEgo.cpp
Line Branch Exec Source
1 // The ego layout of the relationship graph (declared in RelationGraphLayout.h,
2 // split from RelationGraphLayout.cpp): the centre inside its family tree,
3 // the other relationships in columns beside it.
4 #include "RelationGraphLayout.h"
5
6 #include "RelationGraphBlocks.h"
7 #include "RelationGraphRows.h"
8 #include "RelationVocabulary.h"
9
10 #include <algorithm>
11
12 namespace RelationGraphLayout {
13
14 namespace {
15
16 // What `node` is to the centre (canonical type; "" when only an introduction or a layer links them).
17 838 QString typeToCentre(const RelationGraph::Graph &graph, int centre, int node) {
18 838 QString best;
19
2/2
✓ Branch 47 → 4 taken 39150 times.
✓ Branch 47 → 48 taken 838 times.
39988 for (const RelationGraph::Edge &e : graph.edges) {
20
8/8
✓ Branch 5 → 6 taken 3062 times.
✓ Branch 5 → 8 taken 36088 times.
✓ Branch 6 → 7 taken 154 times.
✓ Branch 6 → 8 taken 2908 times.
✓ Branch 9 → 10 taken 7510 times.
✓ Branch 9 → 12 taken 31640 times.
✓ Branch 10 → 11 taken 86 times.
✓ Branch 10 → 12 taken 7424 times.
39150 const bool out = e.from == centre && e.to == node, in = e.to == centre && e.from == node;
21
9/10
✓ Branch 13 → 14 taken 38996 times.
✓ Branch 13 → 15 taken 154 times.
✓ Branch 14 → 15 taken 86 times.
✓ Branch 14 → 21 taken 38910 times.
✓ Branch 17 → 18 taken 106 times.
✓ Branch 17 → 22 taken 134 times.
✓ Branch 20 → 21 taken 106 times.
✗ Branch 20 → 22 not taken.
✓ Branch 23 → 24 taken 39016 times.
✓ Branch 23 → 25 taken 134 times.
39150 if ((!out && !in) || (e.kind != QLatin1String("relation") && e.kind != QLatin1String("inferred")))
22 39016 continue;
23
1/1
✓ Branch 25 → 26 taken 134 times.
134 const QString inverse = RelationVocabulary::inverseOf(e.type);
24
2/6
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 31 taken 134 times.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 32 not taken.
✓ Branch 33 → 34 taken 134 times.
✗ Branch 33 → 43 not taken.
134 if (best.isEmpty() || e.kind == QLatin1String("relation"))
25
4/5
✓ Branch 34 → 35 taken 38 times.
✓ Branch 34 → 37 taken 96 times.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 38 taken 38 times.
✓ Branch 39 → 40 taken 134 times.
134 best = RelationVocabulary::canonical(out || inverse.isEmpty() ? e.type : inverse);
26 134 }
27 838 return best;
28 ✗ }
29
30 // Inside a column: managers above colleagues above the team; friends above acquaintances.
31 838 int roleRank(const QString &type) {
32 3 static const QStringList order{QStringLiteral("x-manager"), QStringLiteral("colleague"), QStringLiteral("co-worker"),
33 3 QStringLiteral("agent"), QStringLiteral("x-assisted"), QStringLiteral("x-report"),
34
5/10
✓ Branch 2 → 3 taken 3 times.
✓ Branch 2 → 44 taken 835 times.
✓ Branch 4 → 5 taken 3 times.
✗ Branch 4 → 44 not taken.
✓ Branch 33 → 34 taken 24 times.
✓ Branch 33 → 35 taken 3 times.
✗ Branch 52 → 53 not taken.
✗ Branch 52 → 54 not taken.
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 87 not taken.
868 QStringLiteral("friend"), QStringLiteral("acquaintance")};
35 838 const int index = int(order.indexOf(type));
36
2/2
✓ Branch 45 → 46 taken 710 times.
✓ Branch 45 → 48 taken 128 times.
838 return index < 0 ? int(order.size()) : index;
37 27 }
38
39 struct Column {
40 QString sector;
41 int side = 1; // −1 left, +1 right
42 int lane = 0; // the group's bus and spine on its side
43 QList<int> members;
44 };
45
46 // The shown members of every family that has someone among `nodes` join
47 // them (repeated, so a family reached through a joined member comes, too):
48 // a family stays in one place instead of one area in the tree and another
49 // in a column.
50 67 QSet<int> withTheirFamilies(const RelationGraph::Graph &graph, const QList<int> &nodes) {
51 67 QSet<int> joined(nodes.cbegin(), nodes.cend());
52
2/2
✓ Branch 38 → 6 taken 69 times.
✓ Branch 38 → 39 taken 67 times.
136 for (bool grew = true; grew;) {
53 69 grew = false;
54
2/2
✓ Branch 36 → 8 taken 57 times.
✓ Branch 36 → 37 taken 69 times.
126 for (const RelationGraph::Area &area : graph.areas) {
55
3/3
✓ Branch 11 → 12 taken 57 times.
✓ Branch 12 → 13 taken 25 times.
✓ Branch 12 → 14 taken 32 times.
116 if (std::none_of(area.members.cbegin(), area.members.cend(), [&](int m) { return joined.contains(m); }))
56 25 continue;
57
2/2
✓ Branch 32 → 16 taken 91 times.
✓ Branch 32 → 33 taken 32 times.
123 for (int member : area.members)
58 91 if (const RelationGraph::Node &node = graph.nodes.at(member);
59
6/8
✓ Branch 19 → 20 taken 2 times.
✓ Branch 19 → 26 taken 89 times.
✓ Branch 21 → 22 taken 2 times.
✗ Branch 21 → 26 not taken.
✓ Branch 24 → 25 taken 2 times.
✗ Branch 24 → 26 not taken.
✓ Branch 27 → 28 taken 2 times.
✓ Branch 27 → 30 taken 89 times.
91 !joined.contains(member) && isShown(node) && node.sector != QLatin1String("suggestions")) {
60
1/1
✓ Branch 28 → 29 taken 2 times.
2 joined.insert(member);
61 2 grew = true;
62 }
63 }
64 }
65 67 return joined;
66 ✗ }
67
68 // A family whose members are related to the centre in different ways (a
69 // friend on the left, the introducer on the right) moves into the column
70 // that holds most of them (on a tie the first), so its area is one.
71 67 void oneColumnPerFamily(const RelationGraph::Graph &graph, QList<Column> *columns) {
72
2/2
✓ Branch 58 → 4 taken 53 times.
✓ Branch 58 → 59 taken 67 times.
120 for (const RelationGraph::Area &area : graph.areas) {
73
1/1
✓ Branch 6 → 7 taken 53 times.
53 QList<int> count(columns->size(), 0);
74
2/2
✓ Branch 22 → 8 taken 212 times.
✓ Branch 22 → 23 taken 53 times.
265 for (int c = 0; c < columns->size(); ++c)
75
2/2
✓ Branch 19 → 10 taken 436 times.
✓ Branch 19 → 20 taken 212 times.
648 for (int member : area.members)
76
4/4
✓ Branch 11 → 12 taken 436 times.
✓ Branch 13 → 14 taken 24 times.
✓ Branch 13 → 15 taken 412 times.
✓ Branch 16 → 17 taken 436 times.
436 count[c] += (*columns)[c].members.contains(member) ? 1 : 0;
77
1/1
✓ Branch 26 → 27 taken 53 times.
53 const int target = int(std::max_element(count.cbegin(), count.cend()) - count.cbegin());
78
2/2
✓ Branch 29 → 30 taken 30 times.
✓ Branch 29 → 31 taken 23 times.
53 if (count.at(target) == 0)
79 30 continue;
80
2/2
✓ Branch 49 → 32 taken 92 times.
✓ Branch 49 → 50 taken 23 times.
115 for (int c = 0; c < columns->size(); ++c)
81
2/2
✓ Branch 46 → 34 taken 96 times.
✓ Branch 46 → 47 taken 92 times.
188 for (int member : area.members)
82
8/8
✓ Branch 35 → 36 taken 72 times.
✓ Branch 35 → 40 taken 24 times.
✓ Branch 36 → 37 taken 72 times.
✓ Branch 37 → 38 taken 72 times.
✓ Branch 38 → 39 taken 1 time.
✓ Branch 38 → 40 taken 71 times.
✓ Branch 41 → 42 taken 1 time.
✓ Branch 41 → 44 taken 95 times.
96 if (c != target && (*columns)[c].members.removeOne(member))
83
2/2
✓ Branch 42 → 43 taken 1 time.
✓ Branch 43 → 44 taken 1 time.
1 (*columns)[target].members.append(member);
84 53 }
85 67 }
86
87 // The column's people in their order, each family's members right after
88 // the first of them, so a family stands together.
89 101 QList<int> familiesTogether(const RelationGraph::Graph &graph, const QList<int> &sorted) {
90 101 QList<int> out;
91
2/2
✓ Branch 35 → 4 taken 236 times.
✓ Branch 35 → 36 taken 101 times.
337 for (int node : sorted) {
92
2/2
✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 8 taken 235 times.
236 if (out.contains(node))
93 1 continue;
94
1/1
✓ Branch 8 → 9 taken 235 times.
235 out.append(node);
95
2/2
✓ Branch 31 → 11 taken 193 times.
✓ Branch 31 → 32 taken 235 times.
428 for (const RelationGraph::Area &area : graph.areas)
96
2/2
✓ Branch 13 → 14 taken 23 times.
✓ Branch 13 → 29 taken 170 times.
193 if (area.members.contains(node))
97
2/2
✓ Branch 27 → 16 taken 47 times.
✓ Branch 27 → 28 taken 23 times.
70 for (int mate : sorted)
98
6/6
✓ Branch 18 → 19 taken 24 times.
✓ Branch 18 → 22 taken 23 times.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 20 → 22 taken 23 times.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 25 taken 46 times.
47 if (area.members.contains(mate) && !out.contains(mate))
99
1/1
✓ Branch 24 → 25 taken 1 time.
1 out.append(mate);
100 }
101 101 return out;
102 ✗ }
103
104 } // namespace
105
106 67 Layout egoLayout(const RelationGraph::Graph &graph, const Options &) {
107 67 Layout layout;
108 67 const int n = int(graph.nodes.size());
109
1/1
✓ Branch 3 → 4 taken 67 times.
67 layout.positions = QList<QPointF>(n);
110
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 67 times.
67 if (n == 0)
111 ✗ return layout;
112 67 int centre = 0;
113
2/2
✓ Branch 13 → 9 taken 599 times.
✓ Branch 13 → 14 taken 67 times.
666 for (int i = 0; i < n; ++i)
114
2/2
✓ Branch 10 → 11 taken 67 times.
✓ Branch 10 → 12 taken 532 times.
599 if (graph.nodes.at(i).center)
115 67 centre = i;
116 // The family as a tree around the centre.
117
1/1
✓ Branch 14 → 15 taken 67 times.
67 QList<int> candidates{centre};
118
2/2
✓ Branch 29 → 16 taken 599 times.
✓ Branch 29 → 30 taken 67 times.
666 for (int i = 0; i < n; ++i)
119
7/8
✓ Branch 16 → 17 taken 532 times.
✓ Branch 16 → 25 taken 67 times.
✓ Branch 19 → 20 taken 532 times.
✗ Branch 19 → 25 not taken.
✓ Branch 23 → 24 taken 299 times.
✓ Branch 23 → 25 taken 233 times.
✓ Branch 26 → 27 taken 299 times.
✓ Branch 26 → 28 taken 300 times.
599 if (i != centre && isShown(graph.nodes.at(i)) && graph.nodes.at(i).sector == QLatin1String("family"))
120
1/1
✓ Branch 27 → 28 taken 299 times.
299 candidates.append(i);
121
1/1
✓ Branch 30 → 31 taken 67 times.
67 const QSet<int> joined = withTheirFamilies(graph, candidates);
122
2/2
✓ Branch 41 → 32 taken 599 times.
✓ Branch 41 → 42 taken 67 times.
666 for (int i = 0; i < n; ++i)
123
6/6
✓ Branch 33 → 34 taken 368 times.
✓ Branch 33 → 37 taken 231 times.
✓ Branch 35 → 36 taken 2 times.
✓ Branch 35 → 37 taken 366 times.
✓ Branch 38 → 39 taken 2 times.
✓ Branch 38 → 40 taken 597 times.
599 if (joined.contains(i) && !candidates.contains(i))
124
1/1
✓ Branch 39 → 40 taken 2 times.
2 candidates.append(i);
125
1/1
✓ Branch 42 → 43 taken 67 times.
67 const QHash<int, int> generation = generations(graph, candidates, centre);
126 // A household member without known kinship shares the centre's row, so
127 // does someone who is in a family with another of the tree.
128 12 const auto sharesAFamily = [&](int i) {
129 12 return std::any_of(graph.areas.cbegin(), graph.areas.cend(), [&](const RelationGraph::Area &area) {
130 ✗ return area.members.contains(i) && std::any_of(area.members.cbegin(), area.members.cend(), [&](int m) {
131 ✗ return m != i && joined.contains(m);
132 ✗ });
133 12 });
134 67 };
135 67 QList<int> family;
136
2/2
✓ Branch 59 → 46 taken 368 times.
✓ Branch 59 → 60 taken 67 times.
435 for (int i : std::as_const(candidates))
137
8/9
✓ Branch 48 → 49 taken 16 times.
✓ Branch 48 → 53 taken 352 times.
✓ Branch 50 → 51 taken 12 times.
✓ Branch 50 → 53 taken 4 times.
✓ Branch 51 → 52 taken 12 times.
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 54 taken 12 times.
✓ Branch 55 → 56 taken 356 times.
✓ Branch 55 → 57 taken 12 times.
368 if (generation.contains(i) || graph.nodes.at(i).depth <= 1 || sharesAFamily(i))
138
1/1
✓ Branch 56 → 57 taken 356 times.
356 family.append(i);
139
1/1
✓ Branch 60 → 61 taken 67 times.
67 const QHash<int, QPointF> tree = rows(graph, family, generation);
140 67 const double originX = tree.value(centre).x();
141 67 double left = 0, right = 0, bottom = 0;
142
2/2
✓ Branch 84 → 64 taken 356 times.
✓ Branch 84 → 85 taken 67 times.
423 for (auto it = tree.cbegin(); it != tree.cend(); ++it) {
143
1/1
✓ Branch 68 → 69 taken 356 times.
356 layout.positions[it.key()] = it.value() - QPointF(originX, 0);
144 356 left = std::min(left, layout.positions.at(it.key()).x());
145 356 right = std::max(right, layout.positions.at(it.key()).x());
146 356 bottom = std::max(bottom, layout.positions.at(it.key()).y());
147 }
148 // Everyone else in columns beside the family: friends and other left, work and introductions right.
149 ✗ QList<Column> columns{{QStringLiteral("friends"), -1, 0, {}},
150 67 {QStringLiteral("other"), -1, 1, {}},
151 67 {QStringLiteral("work"), 1, 0, {}},
152
2/4
✓ Branch 99 → 100 taken 268 times.
✓ Branch 99 → 101 taken 67 times.
✗ Branch 306 → 307 not taken.
✗ Branch 306 → 308 not taken.
335 {QStringLiteral("introductions"), 1, 1, {}}};
153 67 QList<int> suggested, familyMore;
154
2/2
✓ Branch 152 → 106 taken 599 times.
✓ Branch 152 → 153 taken 67 times.
666 for (int i = 0; i < n; ++i) {
155 599 const RelationGraph::Node &node = graph.nodes.at(i);
156
5/6
✓ Branch 108 → 109 taken 243 times.
✓ Branch 108 → 110 taken 356 times.
✗ Branch 109 → 110 not taken.
✓ Branch 109 → 111 taken 243 times.
✓ Branch 112 → 113 taken 356 times.
✓ Branch 112 → 114 taken 243 times.
599 if (tree.contains(i) || node.family)
157 363 continue;
158
2/2
✓ Branch 116 → 117 taken 7 times.
✓ Branch 116 → 119 taken 236 times.
243 if (node.sector == QLatin1String("suggestions")) {
159
1/1
✓ Branch 117 → 118 taken 7 times.
7 suggested.append(i);
160 7 continue;
161 }
162
4/6
✓ Branch 121 → 122 taken 12 times.
✓ Branch 121 → 124 taken 224 times.
✗ Branch 122 → 123 not taken.
✓ Branch 122 → 124 taken 12 times.
✗ Branch 125 → 126 not taken.
✓ Branch 125 → 128 taken 236 times.
236 if (node.sector == QLatin1String("family") && node.moreCount > 0) {
163 ✗ familyMore.append(i);
164 ✗ continue;
165 }
166
4/4
✓ Branch 130 → 131 taken 12 times.
✓ Branch 130 → 134 taken 224 times.
✓ Branch 135 → 136 taken 12 times.
✓ Branch 135 → 137 taken 224 times.
248 const QString sector = node.sector == QLatin1String("family") ? QStringLiteral("other") : node.sector;
167
3/3
✓ Branch 137 → 138 taken 236 times.
✓ Branch 138 → 139 taken 236 times.
✓ Branch 139 → 140 taken 236 times.
765 auto column = std::find_if(columns.begin(), columns.end(), [&](const Column &c) { return c.sector == sector; });
168
3/6
✓ Branch 140 → 141 taken 236 times.
✓ Branch 142 → 143 taken 236 times.
✗ Branch 142 → 144 not taken.
✗ Branch 144 → 145 not taken.
✗ Branch 145 → 146 not taken.
✓ Branch 147 → 148 taken 236 times.
236 (column != columns.end() ? column : columns.begin() + 1)->members.append(i);
169 236 }
170
1/1
✓ Branch 153 → 154 taken 67 times.
67 oneColumnPerFamily(graph, &columns);
171
1/2
✗ Branch 162 → 157 not taken.
✓ Branch 162 → 163 taken 67 times.
67 for (int i : std::as_const(familyMore)) { // "+N more" at the end of the centre's row
172 ✗ right += TreeGap;
173 ✗ layout.positions[i] = {right, 0};
174 }
175 510 const auto byRole = [&](int a, int b) {
176 510 const RelationGraph::Node &na = graph.nodes.at(a), &nb = graph.nodes.at(b);
177
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 510 times.
510 if ((na.moreCount > 0) != (nb.moreCount > 0))
178 ✗ return nb.moreCount > 0; // "+N more" last
179
2/2
✓ Branch 6 → 7 taken 91 times.
✓ Branch 6 → 8 taken 419 times.
510 if (na.depth != nb.depth)
180 91 return na.depth < nb.depth;
181
4/4
✓ Branch 8 → 9 taken 419 times.
✓ Branch 9 → 10 taken 419 times.
✓ Branch 11 → 12 taken 419 times.
✓ Branch 12 → 13 taken 419 times.
419 const int ra = roleRank(typeToCentre(graph, centre, a)), rb = roleRank(typeToCentre(graph, centre, b));
182
2/2
✓ Branch 14 → 15 taken 10 times.
✓ Branch 14 → 16 taken 409 times.
419 if (ra != rb)
183 10 return ra < rb;
184 409 const int c = na.name.localeAwareCompare(nb.name);
185
1/2
✓ Branch 17 → 18 taken 409 times.
✗ Branch 17 → 19 not taken.
409 return c != 0 ? c < 0 : na.key < nb.key;
186 67 };
187 struct Lane {
188 double busY = 0;
189 double spineX = 0;
190 };
191 67 QHash<int, Lane> laneOf; // first-ring member → its group's bus
192 67 double columnsBottom = 0;
193
2/2
✓ Branch 225 → 165 taken 134 times.
✓ Branch 225 → 226 taken 67 times.
201 for (const int side : {-1, 1}) {
194 // The groups of a side are stacked and centred on the centre's row; sub-columns go outwards,
195 // every second one half a step lower so the lines into it pass between the people of the first.
196
2/2
✓ Branch 165 → 166 taken 67 times.
✓ Branch 165 → 168 taken 67 times.
134 const double innerX = side > 0 ? std::max(right, 0.0) + ColumnGap : std::min(left, 0.0) - ColumnGap;
197 134 double height = 0;
198
4/4
✓ Branch 170 → 171 taken 134 times.
✓ Branch 171 → 172 taken 134 times.
✓ Branch 191 → 173 taken 536 times.
✓ Branch 191 → 192 taken 134 times.
670 for (Column &column : columns)
199
6/6
✓ Branch 174 → 175 taken 268 times.
✓ Branch 174 → 178 taken 268 times.
✓ Branch 176 → 177 taken 101 times.
✓ Branch 176 → 178 taken 167 times.
✓ Branch 179 → 180 taken 101 times.
✓ Branch 179 → 189 taken 435 times.
536 if (column.side == side && !column.members.isEmpty()) {
200
3/3
✓ Branch 180 → 181 taken 101 times.
✓ Branch 181 → 182 taken 101 times.
✓ Branch 182 → 183 taken 101 times.
101 std::sort(column.members.begin(), column.members.end(), byRole);
201
1/1
✓ Branch 183 → 184 taken 101 times.
101 column.members = familiesTogether(graph, column.members);
202 101 height += std::min<int>(int(column.members.size()), ColumnHeight) * ColumnStep + ColumnStep / 2;
203 }
204 134 double top = -height / 2 + ColumnStep / 2;
205
2/2
✓ Branch 223 → 195 taken 536 times.
✓ Branch 223 → 224 taken 134 times.
670 for (const Column &column : std::as_const(columns)) {
206
6/6
✓ Branch 196 → 197 taken 268 times.
✓ Branch 196 → 199 taken 268 times.
✓ Branch 198 → 199 taken 167 times.
✓ Branch 198 → 200 taken 101 times.
✓ Branch 201 → 202 taken 435 times.
✓ Branch 201 → 203 taken 101 times.
536 if (column.side != side || column.members.isEmpty())
207 435 continue;
208 // The bus runs in the corridor between the centre's row and the next one
209 // below (under the names, above the children's descent bars), where it
210 // only crosses lines of descent; the lanes of one side 9 px apart.
211 101 const Lane lane{TreeRowHeight / 2 + 9 * column.lane, innerX - side * (44 + 9 * column.lane)};
212 // The group's heading above its first person.
213 101 layout.groups.append({column.sector, QPointF(innerX, top - ColumnStep * 0.55)});
214
2/2
✓ Branch 217 → 208 taken 236 times.
✓ Branch 217 → 218 taken 101 times.
337 for (int k = 0; k < column.members.size(); ++k) {
215 236 const int sub = k / ColumnHeight;
216 236 const QPointF at(innerX + side * sub * ColumnGap, top + (k % ColumnHeight) * ColumnStep + (sub % 2) * ColumnStep / 2);
217
1/1
✓ Branch 210 → 211 taken 236 times.
236 layout.positions[column.members.at(k)] = at;
218
1/1
✓ Branch 212 → 213 taken 236 times.
236 laneOf.insert(column.members.at(k), lane);
219 236 columnsBottom = std::max(columnsBottom, at.y());
220 }
221 101 top += std::min<int>(int(column.members.size()), ColumnHeight) * ColumnStep + ColumnStep / 2;
222 }
223 }
224
3/3
✓ Branch 226 → 227 taken 67 times.
✓ Branch 227 → 228 taken 67 times.
✓ Branch 228 → 229 taken 67 times.
67 std::sort(suggested.begin(), suggested.end(), byRole);
225 67 const double suggestionRow = std::max(bottom, columnsBottom) + 140;
226
2/2
✓ Branch 237 → 231 taken 7 times.
✓ Branch 237 → 238 taken 67 times.
74 for (int k = 0; k < suggested.size(); ++k)
227
1/1
✓ Branch 234 → 235 taken 7 times.
7 layout.positions[suggested.at(k)] = {-TreeGap * (suggested.size() - 1) / 2 + TreeGap * k, suggestionRow};
228 // A hidden family card sits in the middle of the shown people (never drawn).
229
2/2
✓ Branch 245 → 239 taken 599 times.
✓ Branch 245 → 246 taken 67 times.
666 for (int i = 0; i < n; ++i)
230
1/2
✗ Branch 240 → 241 not taken.
✓ Branch 240 → 244 taken 599 times.
599 if (graph.nodes.at(i).family)
231 ✗ layout.positions[i] = layout.positions.at(centre);
232
1/1
✓ Branch 246 → 247 taken 67 times.
67 layout.routes = routes(graph, layout.positions);
233 // Lines between the centre and a column: one bus per group, never across the family.
234
2/2
✓ Branch 287 → 250 taken 1199 times.
✓ Branch 287 → 288 taken 67 times.
1266 for (int e = 0; e < graph.edges.size(); ++e) {
235 1199 const RelationGraph::Edge &edge = graph.edges.at(e);
236
4/4
✓ Branch 251 → 252 taken 305 times.
✓ Branch 251 → 253 taken 894 times.
✓ Branch 253 → 254 taken 162 times.
✓ Branch 253 → 255 taken 732 times.
1199 const int other = edge.from == centre ? edge.to : edge.to == centre ? edge.from : -1;
237
6/8
✓ Branch 257 → 258 taken 467 times.
✓ Branch 257 → 266 taken 732 times.
✓ Branch 259 → 260 taken 160 times.
✓ Branch 259 → 266 taken 307 times.
✓ Branch 261 → 262 taken 160 times.
✗ Branch 261 → 266 not taken.
✗ Branch 265 → 266 not taken.
✓ Branch 265 → 267 taken 160 times.
1359 if (other < 0 || !laneOf.contains(other) || graph.nodes.at(other).depth != 1 ||
238
2/2
✓ Branch 268 → 269 taken 1039 times.
✓ Branch 268 → 270 taken 160 times.
1359 layout.routes.at(e).shape == QLatin1String("none"))
239 1039 continue;
240 160 const Lane lane = laneOf.value(other);
241
1/1
✓ Branch 273 → 274 taken 160 times.
160 const Route bus = busRoute(layout.positions.at(centre), layout.positions.at(other), lane.busY, lane.spineX);
242
4/8
✓ Branch 275 → 276 taken 81 times.
✓ Branch 275 → 277 taken 79 times.
✓ Branch 279 → 280 taken 79 times.
✓ Branch 280 → 281 taken 160 times.
✗ Branch 363 → 364 not taken.
✗ Branch 363 → 365 not taken.
✗ Branch 368 → 369 not taken.
✗ Branch 368 → 370 not taken.
160 layout.routes[e] = Route{bus.shape, edge.from == centre ? bus.points : QList<QPointF>(bus.points.crbegin(), bus.points.crend())};
243 160 }
244 67 return layout;
245 503 }
246
247 6 QList<QPointF> ego(const RelationGraph::Graph &graph, const Options &options) {
248
1/1
✓ Branch 2 → 3 taken 6 times.
6 return egoLayout(graph, options).positions;
249 }
250
251 } // namespace RelationGraphLayout
252