presentation/ConflictRows.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ConflictRows.h" | ||
| 2 | |||
| 3 | #include <QHash> | ||
| 4 | |||
| 5 | #include "data/TextMerge3.h" | ||
| 6 | |||
| 7 | #include <QCoreApplication> | ||
| 8 | #include <QSet> | ||
| 9 | #include <QVariantMap> | ||
| 10 | |||
| 11 | namespace ConflictRows { | ||
| 12 | |||
| 13 | namespace { | ||
| 14 | |||
| 15 | using Side = ConflictValueText::Side; | ||
| 16 | |||
| 17 | 370 | QString pickName(Merge::Choice choice) { | |
| 18 |
3/6✓ Branch 2 → 3 taken 248 times.
✓ Branch 2 → 8 taken 91 times.
✗ Branch 2 → 13 not taken.
✗ Branch 2 → 18 not taken.
✓ Branch 2 → 23 taken 31 times.
✗ Branch 2 → 24 not taken.
|
370 | switch (choice) { |
| 19 | 248 | case Merge::Choice::Local: | |
| 20 | 248 | return QStringLiteral("local"); | |
| 21 | 91 | case Merge::Choice::Server: | |
| 22 | 91 | return QStringLiteral("server"); | |
| 23 | ✗ | case Merge::Choice::Both: | |
| 24 | ✗ | return QStringLiteral("both"); | |
| 25 | ✗ | case Merge::Choice::Base: | |
| 26 | ✗ | return QStringLiteral("base"); | |
| 27 | 31 | case Merge::Choice::Edited: | |
| 28 | case Merge::Choice::None: | ||
| 29 | 31 | break; | |
| 30 | } | ||
| 31 | 31 | return QStringLiteral("open"); | |
| 32 | } | ||
| 33 | |||
| 34 | 370 | QString hunkKindName(TextMerge::HunkKind kind) { | |
| 35 |
4/6✓ Branch 2 → 3 taken 171 times.
✓ Branch 2 → 8 taken 77 times.
✓ Branch 2 → 13 taken 91 times.
✗ Branch 2 → 18 not taken.
✓ Branch 2 → 23 taken 31 times.
✗ Branch 2 → 24 not taken.
|
370 | switch (kind) { |
| 36 | 171 | case TextMerge::HunkKind::Same: | |
| 37 | 171 | return QStringLiteral("same"); | |
| 38 | 77 | case TextMerge::HunkKind::LocalOnly: | |
| 39 | 77 | return QStringLiteral("local"); | |
| 40 | 91 | case TextMerge::HunkKind::ServerOnly: | |
| 41 | 91 | return QStringLiteral("server"); | |
| 42 | ✗ | case TextMerge::HunkKind::BothSame: | |
| 43 | ✗ | return QStringLiteral("both-same"); | |
| 44 | 31 | case TextMerge::HunkKind::Conflict: | |
| 45 | 31 | break; | |
| 46 | } | ||
| 47 | 31 | return QStringLiteral("conflict"); | |
| 48 | } | ||
| 49 | |||
| 50 | 1103 | QString stateOfMembers(const Merge::Plan &plan, const QList<const Merge::Item *> &members, bool conflict) { | |
| 51 | 1103 | bool open = false, edited = false; | |
| 52 |
2/2✓ Branch 16 → 4 taken 1386 times.
✓ Branch 16 → 17 taken 1103 times.
|
2489 | for (const Merge::Item *item : members) { |
| 53 |
5/5✓ Branch 5 → 6 taken 1295 times.
✓ Branch 5 → 8 taken 91 times.
✓ Branch 6 → 7 taken 1295 times.
✓ Branch 7 → 8 taken 337 times.
✓ Branch 7 → 9 taken 958 times.
|
1386 | open = open || Merge::itemOpen(plan, *item); |
| 54 |
3/4✓ Branch 10 → 11 taken 1386 times.
✗ Branch 10 → 12 not taken.
✓ Branch 11 → 12 taken 6 times.
✓ Branch 11 → 13 taken 1380 times.
|
1386 | edited = edited || item->choice == Merge::Choice::Edited; |
| 55 | } | ||
| 56 |
2/2✓ Branch 17 → 18 taken 337 times.
✓ Branch 17 → 23 taken 766 times.
|
1103 | if (open) |
| 57 | 337 | return QStringLiteral("open"); | |
| 58 |
2/2✓ Branch 23 → 24 taken 6 times.
✓ Branch 23 → 29 taken 760 times.
|
766 | if (edited) |
| 59 | 6 | return QStringLiteral("edited"); | |
| 60 |
2/2✓ Branch 29 → 30 taken 78 times.
✓ Branch 29 → 35 taken 682 times.
|
760 | if (conflict) |
| 61 | 78 | return QStringLiteral("decided"); | |
| 62 | 682 | bool local = false, server = false; | |
| 63 |
2/2✓ Branch 48 → 37 taken 856 times.
✓ Branch 48 → 49 taken 682 times.
|
1538 | for (const Merge::Item *item : members) { |
| 64 |
4/4✓ Branch 38 → 39 taken 835 times.
✓ Branch 38 → 40 taken 21 times.
✓ Branch 39 → 40 taken 330 times.
✓ Branch 39 → 41 taken 505 times.
|
856 | local = local || item->state == Merge::State::LocalOnly; |
| 65 |
4/4✓ Branch 42 → 43 taken 758 times.
✓ Branch 42 → 44 taken 98 times.
✓ Branch 43 → 44 taken 409 times.
✓ Branch 43 → 45 taken 349 times.
|
856 | server = server || item->state == Merge::State::ServerOnly; |
| 66 | } | ||
| 67 |
8/8✓ Branch 50 → 51 taken 249 times.
✓ Branch 50 → 54 taken 81 times.
✓ Branch 54 → 55 taken 409 times.
✓ Branch 54 → 59 taken 24 times.
✓ Branch 55 → 56 taken 328 times.
✓ Branch 55 → 59 taken 81 times.
✓ Branch 67 → 68 taken 249 times.
✓ Branch 67 → 69 taken 433 times.
|
1364 | return local && !server ? QStringLiteral("local") : server && !local ? QStringLiteral("server") |
| 68 |
6/6✓ Branch 49 → 50 taken 330 times.
✓ Branch 49 → 54 taken 352 times.
✓ Branch 63 → 64 taken 105 times.
✓ Branch 63 → 65 taken 577 times.
✓ Branch 65 → 66 taken 328 times.
✓ Branch 65 → 67 taken 354 times.
|
2046 | : QStringLiteral("both-same"); |
| 69 | } | ||
| 70 | |||
| 71 | 1698 | QString choiceOfMembers(const QList<const Merge::Item *> &members, bool conflictOnly) { | |
| 72 | 1698 | QString choice; | |
| 73 |
2/2✓ Branch 31 → 4 taken 2063 times.
✓ Branch 31 → 32 taken 1512 times.
|
3575 | for (const Merge::Item *item : members) { |
| 74 |
4/4✓ Branch 5 → 6 taken 445 times.
✓ Branch 5 → 8 taken 1618 times.
✓ Branch 6 → 7 taken 13 times.
✓ Branch 6 → 8 taken 432 times.
|
2063 | if (conflictOnly && item->state != Merge::State::Conflict) |
| 75 | 13 | continue; | |
| 76 |
4/4✓ Branch 8 → 9 taken 336 times.
✓ Branch 8 → 10 taken 1714 times.
✓ Branch 10 → 11 taken 1714 times.
✓ Branch 12 → 13 taken 1714 times.
|
2050 | const QString name = item->choice == Merge::Choice::None ? QString() : QString::fromLatin1(Merge::choiceName(item->choice)); |
| 77 |
2/2✓ Branch 14 → 15 taken 1776 times.
✓ Branch 14 → 16 taken 274 times.
|
2050 | if (choice.isNull()) |
| 78 | 1776 | choice = name; | |
| 79 |
2/2✓ Branch 17 → 18 taken 186 times.
✓ Branch 17 → 23 taken 88 times.
|
274 | else if (choice != name) |
| 80 | 186 | return QStringLiteral("mixed"); | |
| 81 | 2050 | } | |
| 82 |
2/2✓ Branch 33 → 34 taken 258 times.
✓ Branch 33 → 35 taken 1254 times.
|
1512 | return choice.isNull() ? QString() : choice; |
| 83 | 1698 | } | |
| 84 | |||
| 85 | 846 | Side sideOf(Merge::Choice choice) { | |
| 86 |
2/2✓ Branch 2 → 3 taken 439 times.
✓ Branch 2 → 4 taken 407 times.
|
846 | return choice == Merge::Choice::Server ? Side::Server : choice == Merge::Choice::Base ? Side::Base : Side::Local; |
| 87 | } | ||
| 88 | |||
| 89 | 978 | void fillTexts(Row *row, const Merge::Plan &plan, const QList<const Merge::Item *> &members, | |
| 90 | const ConflictValueText::Context &context) { | ||
| 91 | 3561 | const auto present = [&members](Side side) { | |
| 92 |
2/2✓ Branch 15 → 4 taken 3676 times.
✓ Branch 15 → 16 taken 449 times.
|
4125 | for (const Merge::Item *item : members) { |
| 93 |
4/4✓ Branch 5 → 6 taken 1339 times.
✓ Branch 5 → 7 taken 2337 times.
✓ Branch 7 → 8 taken 1293 times.
✓ Branch 7 → 9 taken 1044 times.
|
3676 | const Merge::Value &value = side == Side::Local ? item->local : side == Side::Server ? item->server : item->base; |
| 94 |
2/2✓ Branch 11 → 12 taken 3112 times.
✓ Branch 11 → 13 taken 564 times.
|
3676 | if (value.present) |
| 95 | 3112 | return true; | |
| 96 | } | ||
| 97 | 449 | return false; | |
| 98 | 978 | }; | |
| 99 | 3112 | const auto text = [&](Side side) { | |
| 100 |
2/2✓ Branch 3 → 4 taken 2469 times.
✓ Branch 3 → 6 taken 643 times.
|
3112 | if (members.size() == 1) |
| 101 | 2469 | return ConflictValueText::value(plan, *members.first(), side, context); | |
| 102 | 643 | return ConflictValueText::groupValue(plan, members, side, context); | |
| 103 | 978 | }; | |
| 104 | 2934 | const auto source = [&](Side side) { | |
| 105 | 2934 | QStringList lines; | |
| 106 |
2/2✓ Branch 12 → 4 taken 3783 times.
✓ Branch 12 → 13 taken 2934 times.
|
6717 | for (const Merge::Item *item : members) { |
| 107 |
1/1✓ Branch 5 → 6 taken 3783 times.
|
3783 | const QString line = ConflictValueText::source(*item, side); |
| 108 |
2/2✓ Branch 7 → 8 taken 2923 times.
✓ Branch 7 → 9 taken 860 times.
|
3783 | if (!line.isEmpty()) |
| 109 |
1/1✓ Branch 8 → 9 taken 2923 times.
|
2923 | lines.append(line); |
| 110 | 3783 | } | |
| 111 |
1/1✓ Branch 15 → 16 taken 2934 times.
|
5868 | return lines.join(QLatin1Char('\n')); |
| 112 | 2934 | }; | |
| 113 |
1/1✓ Branch 2 → 3 taken 978 times.
|
978 | row->localPresent = present(Side::Local); |
| 114 |
1/1✓ Branch 3 → 4 taken 978 times.
|
978 | row->serverPresent = present(Side::Server); |
| 115 |
1/1✓ Branch 4 → 5 taken 978 times.
|
978 | row->basePresent = present(Side::Base); |
| 116 |
4/4✓ Branch 5 → 6 taken 843 times.
✓ Branch 5 → 7 taken 135 times.
✓ Branch 6 → 9 taken 843 times.
✓ Branch 8 → 9 taken 135 times.
|
978 | row->localText = row->localPresent ? text(Side::Local) : ConflictValueText::absent(*members.first()); |
| 117 |
4/4✓ Branch 11 → 12 taken 896 times.
✓ Branch 11 → 13 taken 82 times.
✓ Branch 12 → 15 taken 896 times.
✓ Branch 14 → 15 taken 82 times.
|
978 | row->serverText = row->serverPresent ? text(Side::Server) : ConflictValueText::absent(*members.first()); |
| 118 |
4/4✓ Branch 17 → 18 taken 765 times.
✓ Branch 17 → 19 taken 213 times.
✓ Branch 18 → 21 taken 765 times.
✓ Branch 20 → 21 taken 213 times.
|
978 | row->baseText = row->basePresent ? text(Side::Base) : ConflictValueText::absent(*members.first()); |
| 119 |
1/1✓ Branch 23 → 24 taken 978 times.
|
978 | row->localSource = source(Side::Local); |
| 120 |
1/1✓ Branch 26 → 27 taken 978 times.
|
978 | row->serverSource = source(Side::Server); |
| 121 |
1/1✓ Branch 29 → 30 taken 978 times.
|
978 | row->baseSource = source(Side::Base); |
| 122 |
2/2✓ Branch 34 → 35 taken 258 times.
✓ Branch 34 → 37 taken 720 times.
|
978 | if (row->state == QLatin1String("open")) { |
| 123 | 258 | row->resultText.clear(); | |
| 124 | 258 | row->resultPresent = false; | |
| 125 | 885 | return; | |
| 126 | } | ||
| 127 | // The result: a uniform choice shows that side's text; a mix (separated | ||
| 128 | // group) lists each member's result. | ||
| 129 |
1/1✓ Branch 37 → 38 taken 720 times.
|
720 | const QString choice = choiceOfMembers(members, false); |
| 130 |
5/6✓ Branch 40 → 41 taken 627 times.
✓ Branch 40 → 45 taken 93 times.
✓ Branch 43 → 44 taken 627 times.
✗ Branch 43 → 45 not taken.
✓ Branch 46 → 47 taken 627 times.
✓ Branch 46 → 57 taken 93 times.
|
720 | if (choice != QLatin1String("mixed") && choice != QLatin1String("edited")) { |
| 131 |
1/1✓ Branch 47 → 48 taken 627 times.
|
627 | const Side side = sideOf(Merge::choiceFromName(choice)); |
| 132 |
1/1✓ Branch 49 → 50 taken 627 times.
|
627 | row->resultPresent = present(side); |
| 133 |
4/4✓ Branch 50 → 51 taken 608 times.
✓ Branch 50 → 52 taken 19 times.
✓ Branch 51 → 54 taken 608 times.
✓ Branch 53 → 54 taken 19 times.
|
627 | row->resultText = row->resultPresent ? text(side) : ConflictValueText::absent(*members.first()); |
| 134 | 627 | return; | |
| 135 | } | ||
| 136 | 93 | QStringList parts; | |
| 137 |
2/2✓ Branch 74 → 59 taken 249 times.
✓ Branch 74 → 75 taken 93 times.
|
342 | for (const Merge::Item *item : members) { |
| 138 | 249 | bool itemPresent = false; | |
| 139 |
1/1✓ Branch 60 → 61 taken 249 times.
|
249 | Merge::resultText(*item, &itemPresent); |
| 140 |
2/2✓ Branch 62 → 63 taken 219 times.
✓ Branch 62 → 68 taken 30 times.
|
249 | if (itemPresent) |
| 141 |
2/2✓ Branch 64 → 65 taken 219 times.
✓ Branch 65 → 66 taken 219 times.
|
219 | parts.append(ConflictValueText::value(plan, *item, sideOf(item->choice), context)); |
| 142 |
3/4✓ Branch 68 → 69 taken 93 times.
✓ Branch 68 → 70 taken 156 times.
✓ Branch 69 → 70 taken 93 times.
✗ Branch 69 → 71 not taken.
|
249 | row->resultPresent = row->resultPresent || itemPresent; |
| 143 | } | ||
| 144 |
1/1✓ Branch 78 → 79 taken 93 times.
|
93 | row->resultText = parts.join(QStringLiteral(" · ")); |
| 145 | 720 | } | |
| 146 | |||
| 147 | 125 | Row textRow(const Merge::Plan &plan, const Merge::Item &item, const ConflictValueText::Context &context) { | |
| 148 | 125 | Row row; | |
| 149 | 125 | row.id = item.id; | |
| 150 | 125 | row.kind = QStringLiteral("text"); | |
| 151 |
2/4✓ Branch 12 → 13 taken 125 times.
✓ Branch 12 → 14 taken 125 times.
✗ Branch 245 → 246 not taken.
✗ Branch 245 → 247 not taken.
|
250 | row.itemIds = {item.id}; |
| 152 | 125 | row.conflict = item.state == Merge::State::Conflict; | |
| 153 |
2/2✓ Branch 14 → 15 taken 125 times.
✓ Branch 15 → 16 taken 125 times.
|
125 | row.state = stateOfMembers(plan, {&item}, row.conflict); |
| 154 |
4/4✓ Branch 19 → 20 taken 79 times.
✓ Branch 19 → 21 taken 46 times.
✓ Branch 21 → 22 taken 46 times.
✓ Branch 23 → 24 taken 46 times.
|
125 | row.choice = item.choice == Merge::Choice::None ? QString() : QString::fromLatin1(Merge::choiceName(item.choice)); |
| 155 | 125 | int here = 0, there = 0; | |
| 156 |
2/2✓ Branch 188 → 27 taken 370 times.
✓ Branch 188 → 189 taken 125 times.
|
495 | for (int index = 0; index < item.hunks.hunks.size(); ++index) { |
| 157 | 370 | const TextMerge::Hunk &hunk = item.hunks.hunks.at(index); | |
| 158 |
2/2✓ Branch 28 → 29 taken 31 times.
✓ Branch 28 → 30 taken 339 times.
|
370 | if (hunk.kind == TextMerge::HunkKind::Conflict) |
| 159 | 31 | row.overlapping = true; | |
| 160 |
4/4✓ Branch 30 → 31 taken 293 times.
✓ Branch 30 → 32 taken 77 times.
✓ Branch 31 → 32 taken 31 times.
✓ Branch 31 → 33 taken 262 times.
|
370 | if (hunk.kind == TextMerge::HunkKind::LocalOnly || hunk.kind == TextMerge::HunkKind::Conflict) |
| 161 | 108 | ++here; | |
| 162 |
4/4✓ Branch 33 → 34 taken 279 times.
✓ Branch 33 → 35 taken 91 times.
✓ Branch 34 → 35 taken 31 times.
✓ Branch 34 → 36 taken 248 times.
|
370 | if (hunk.kind == TextMerge::HunkKind::ServerOnly || hunk.kind == TextMerge::HunkKind::Conflict) |
| 163 | 122 | ++there; | |
| 164 |
1/2✓ Branch 37 → 38 taken 370 times.
✗ Branch 37 → 40 not taken.
|
370 | const Merge::Choice pick = index < item.hunkChoices.size() ? item.hunkChoices.at(index) : Merge::Choice::None; |
| 165 | 370 | QVariantList localWords, serverWords; | |
| 166 |
8/8✓ Branch 41 → 42 taken 31 times.
✓ Branch 41 → 47 taken 339 times.
✓ Branch 43 → 44 taken 19 times.
✓ Branch 43 → 47 taken 12 times.
✓ Branch 45 → 46 taken 18 times.
✓ Branch 45 → 47 taken 1 time.
✓ Branch 48 → 49 taken 18 times.
✓ Branch 48 → 112 taken 352 times.
|
370 | if (hunk.kind == TextMerge::HunkKind::Conflict && hunk.local.size() == 1 && hunk.server.size() == 1) { |
| 167 | // Word highlights inside a changed line (display only, D-19: plain segments). | ||
| 168 |
5/5✓ Branch 51 → 52 taken 18 times.
✓ Branch 52 → 53 taken 18 times.
✓ Branch 53 → 54 taken 18 times.
✓ Branch 78 → 55 taken 47 times.
✓ Branch 78 → 79 taken 18 times.
|
65 | for (const TextMerge::Segment &segment : TextMerge::wordSegments(hunk.server.first(), hunk.local.first())) |
| 169 |
3/5✓ Branch 66 → 67 taken 47 times.
✓ Branch 70 → 71 taken 94 times.
✓ Branch 70 → 72 taken 47 times.
✗ Branch 267 → 268 not taken.
✗ Branch 267 → 269 not taken.
|
253 | localWords.append(QVariantMap{{QStringLiteral("text"), segment.text}, {QStringLiteral("changed"), segment.changed}}); |
| 170 |
5/5✓ Branch 82 → 83 taken 18 times.
✓ Branch 83 → 84 taken 18 times.
✓ Branch 84 → 85 taken 18 times.
✓ Branch 109 → 86 taken 47 times.
✓ Branch 109 → 110 taken 18 times.
|
65 | for (const TextMerge::Segment &segment : TextMerge::wordSegments(hunk.local.first(), hunk.server.first())) |
| 171 |
3/5✓ Branch 97 → 98 taken 47 times.
✓ Branch 101 → 102 taken 94 times.
✓ Branch 101 → 103 taken 47 times.
✗ Branch 298 → 299 not taken.
✗ Branch 298 → 300 not taken.
|
253 | serverWords.append(QVariantMap{{QStringLiteral("text"), segment.text}, {QStringLiteral("changed"), segment.changed}}); |
| 172 | } | ||
| 173 |
1/1✓ Branch 157 → 158 taken 370 times.
|
1110 | row.hunks.append(QVariantMap{{QStringLiteral("index"), index}, |
| 174 |
1/1✓ Branch 119 → 120 taken 370 times.
|
740 | {QStringLiteral("kind"), hunkKindName(hunk.kind)}, |
| 175 |
1/1✓ Branch 126 → 127 taken 370 times.
|
740 | {QStringLiteral("local"), hunk.local.join(QLatin1Char('\n'))}, |
| 176 |
1/1✓ Branch 133 → 134 taken 370 times.
|
740 | {QStringLiteral("server"), hunk.server.join(QLatin1Char('\n'))}, |
| 177 |
1/1✓ Branch 140 → 141 taken 370 times.
|
740 | {QStringLiteral("base"), hunk.base.join(QLatin1Char('\n'))}, |
| 178 | 740 | {QStringLiteral("localWords"), localWords}, | |
| 179 | 740 | {QStringLiteral("serverWords"), serverWords}, | |
| 180 |
3/5✓ Branch 153 → 154 taken 370 times.
✓ Branch 161 → 162 taken 2960 times.
✓ Branch 161 → 163 taken 370 times.
✗ Branch 329 → 330 not taken.
✗ Branch 329 → 331 not taken.
|
3700 | {QStringLiteral("pick"), pickName(pick)}}); |
| 181 | 370 | } | |
| 182 |
4/4✓ Branch 196 → 197 taken 88 times.
✓ Branch 196 → 198 taken 37 times.
✓ Branch 197 → 199 taken 88 times.
✓ Branch 198 → 199 taken 37 times.
|
250 | row.summary = (here == 1 ? QCoreApplication::translate("ConflictRows", "1 change here") |
| 183 | 125 | : QCoreApplication::translate("ConflictRows", "%n changes here", nullptr, here)) + | |
| 184 |
1/1✓ Branch 199 → 200 taken 125 times.
|
500 | QStringLiteral(", ") + |
| 185 |
2/2✓ Branch 192 → 193 taken 125 times.
✓ Branch 200 → 201 taken 125 times.
|
500 | QCoreApplication::translate("ConflictRows", "%n on the server", nullptr, there) + |
| 186 |
4/4✓ Branch 189 → 190 taken 31 times.
✓ Branch 189 → 191 taken 94 times.
✓ Branch 190 → 192 taken 31 times.
✓ Branch 191 → 192 taken 94 times.
|
250 | (row.overlapping ? QCoreApplication::translate("ConflictRows", " — a line changed on both") |
| 187 |
1/1✓ Branch 201 → 202 taken 125 times.
|
125 | : QCoreApplication::translate("ConflictRows", " — no line changed on both")); |
| 188 | 125 | row.localPresent = item.local.present; | |
| 189 | 125 | row.serverPresent = item.server.present; | |
| 190 | 125 | row.basePresent = item.base.present; | |
| 191 | 375 | const auto plain = [&item](const Merge::Value &value, const QString &text) { | |
| 192 |
3/4✓ Branch 2 → 3 taken 40 times.
✓ Branch 2 → 4 taken 335 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 335 times.
|
375 | return !value.present ? ConflictValueText::absent(item) : text.isNull() ? value.text : text; |
| 193 | 125 | }; | |
| 194 |
1/1✓ Branch 211 → 212 taken 125 times.
|
125 | row.localText = plain(item.local, item.localPlain); |
| 195 |
1/1✓ Branch 214 → 215 taken 125 times.
|
125 | row.serverText = plain(item.server, item.serverPlain); |
| 196 |
1/1✓ Branch 217 → 218 taken 125 times.
|
125 | row.baseText = plain(item.base, item.basePlain); |
| 197 | 125 | row.localSource = item.local.text; | |
| 198 | 125 | row.serverSource = item.server.text; | |
| 199 | 125 | row.baseSource = item.base.text; | |
| 200 | 125 | bool present = false; | |
| 201 |
3/3✓ Branch 225 → 226 taken 79 times.
✓ Branch 225 → 227 taken 46 times.
✓ Branch 227 → 228 taken 46 times.
|
125 | row.resultText = row.state == QLatin1String("open") ? QString() : Merge::resultText(item, &present); |
| 202 |
5/6✓ Branch 230 → 231 taken 112 times.
✓ Branch 230 → 233 taken 13 times.
✓ Branch 231 → 232 taken 85 times.
✓ Branch 231 → 233 taken 27 times.
✗ Branch 232 → 233 not taken.
✓ Branch 232 → 240 taken 85 times.
|
125 | if (item.choice == Merge::Choice::Local || item.choice == Merge::Choice::Server || item.choice == Merge::Choice::Base) |
| 203 | 40 | row.resultText = item.choice == Merge::Choice::Local ? row.localText | |
| 204 | 27 | : item.choice == Merge::Choice::Server ? row.serverText | |
| 205 |
3/4✓ Branch 233 → 234 taken 13 times.
✓ Branch 233 → 235 taken 27 times.
✓ Branch 235 → 236 taken 27 times.
✗ Branch 235 → 237 not taken.
|
40 | : row.baseText; |
| 206 | 125 | row.resultPresent = row.state != QLatin1String("open"); | |
| 207 | Q_UNUSED(context); | ||
| 208 | 125 | return row; | |
| 209 | 3737 | } | |
| 210 | |||
| 211 | 978 | void finishRow(Row *row, const Merge::Plan &plan, const QList<const Merge::Item *> &members, | |
| 212 | const ConflictValueText::Context &context) { | ||
| 213 |
2/2✓ Branch 12 → 4 taken 1261 times.
✓ Branch 12 → 13 taken 978 times.
|
2239 | for (const Merge::Item *item : members) { |
| 214 |
1/1✓ Branch 5 → 6 taken 1261 times.
|
1261 | row->itemIds.append(item->id); |
| 215 |
4/4✓ Branch 6 → 7 taken 1152 times.
✓ Branch 6 → 8 taken 109 times.
✓ Branch 7 → 8 taken 336 times.
✓ Branch 7 → 9 taken 816 times.
|
1261 | row->conflict = row->conflict || item->state == Merge::State::Conflict; |
| 216 | } | ||
| 217 |
1/1✓ Branch 13 → 14 taken 978 times.
|
978 | row->state = stateOfMembers(plan, members, row->conflict); |
| 218 |
1/1✓ Branch 16 → 17 taken 978 times.
|
978 | row->choice = choiceOfMembers(members, row->conflict); |
| 219 | 978 | fillTexts(row, plan, members, context); | |
| 220 | 978 | } | |
| 221 | |||
| 222 | } // namespace | ||
| 223 | |||
| 224 | 674 | QList<Row> build(const Merge::Plan &plan, const ConflictValueText::Context &context) { | |
| 225 | 674 | QList<Row> rows; | |
| 226 | 674 | QSet<QString> handled; | |
| 227 | // Indexes instead of a scan per item (G11: a series with 500 overrides has | ||
| 228 | // thousands of items): the items of each component, the members of each | ||
| 229 | // cross-component group and the groups that hold a conflict. | ||
| 230 | 674 | QHash<QString, QList<int>> byParent; | |
| 231 | 674 | QHash<QString, QList<int>> byCrossGroup; | |
| 232 | 674 | QSet<QString> conflictGroups; | |
| 233 | 21162 | const auto scopeKey = [](const Merge::Item &item) { | |
| 234 |
5/5✓ Branch 4 → 5 taken 21162 times.
✓ Branch 5 → 6 taken 24 times.
✓ Branch 5 → 7 taken 21138 times.
✓ Branch 8 → 9 taken 21162 times.
✓ Branch 9 → 10 taken 21162 times.
|
21162 | return (Merge::Plan::crossParentGroup(item.group) ? QString() : item.parent) + QLatin1Char('\n') + item.group; |
| 235 | }; | ||
| 236 |
2/2✓ Branch 24 → 5 taken 62948 times.
✓ Branch 24 → 25 taken 674 times.
|
63622 | for (int index = 0; index < plan.items.size(); ++index) { |
| 237 | 62948 | const Merge::Item &item = plan.items.at(index); | |
| 238 |
2/2✓ Branch 6 → 7 taken 62948 times.
✓ Branch 7 → 8 taken 62948 times.
|
62948 | byParent[item.parent].append(index); |
| 239 |
3/3✓ Branch 8 → 9 taken 62948 times.
✓ Branch 9 → 10 taken 16 times.
✓ Branch 9 → 12 taken 62932 times.
|
62948 | if (Merge::Plan::crossParentGroup(item.group)) |
| 240 |
2/2✓ Branch 10 → 11 taken 16 times.
✓ Branch 11 → 12 taken 16 times.
|
16 | byCrossGroup[item.group].append(index); |
| 241 |
6/6✓ Branch 13 → 14 taken 21071 times.
✓ Branch 13 → 16 taken 41877 times.
✓ Branch 14 → 15 taken 266 times.
✓ Branch 14 → 16 taken 20805 times.
✓ Branch 17 → 18 taken 266 times.
✓ Branch 17 → 22 taken 62682 times.
|
62948 | if (!item.group.isEmpty() && item.state == Merge::State::Conflict) |
| 242 |
2/2✓ Branch 18 → 19 taken 266 times.
✓ Branch 19 → 20 taken 266 times.
|
266 | conflictGroups.insert(scopeKey(item)); |
| 243 | } | ||
| 244 |
2/2✓ Branch 246 → 26 taken 62948 times.
✓ Branch 246 → 247 taken 674 times.
|
63622 | for (int index = 0; index < plan.items.size(); ++index) { |
| 245 | 62948 | const Merge::Item &item = plan.items.at(index); | |
| 246 |
2/2✓ Branch 28 → 29 taken 283 times.
✓ Branch 28 → 30 taken 62665 times.
|
62948 | if (handled.contains(item.id)) |
| 247 | 61845 | continue; | |
| 248 | // Members of the same row: the coupled group (with a conflict, not | ||
| 249 | // separated) or the values of one list property. | ||
| 250 | 62665 | QList<const Merge::Item *> members; | |
| 251 | // J3: "occurrence:<id>" couples an occurrence with the master's EXDATE value. | ||
| 252 |
1/1✓ Branch 30 → 31 taken 62665 times.
|
62665 | const bool crossParent = Merge::Plan::crossParentGroup(item.group); |
| 253 | 299 | const auto collect = [&](const QList<int> &scope, const std::function<bool(const Merge::Item &)> &belongs) { | |
| 254 |
2/2✓ Branch 15 → 4 taken 1942 times.
✓ Branch 15 → 16 taken 299 times.
|
2241 | for (const int other : scope) |
| 255 |
3/3✓ Branch 6 → 7 taken 1942 times.
✓ Branch 7 → 8 taken 582 times.
✓ Branch 7 → 13 taken 1360 times.
|
1942 | if (belongs(plan.items.at(other))) { |
| 256 |
1/1✓ Branch 9 → 10 taken 582 times.
|
582 | members.append(&plan.items.at(other)); |
| 257 |
1/1✓ Branch 11 → 12 taken 582 times.
|
582 | handled.insert(plan.items.at(other).id); |
| 258 | } | ||
| 259 | 299 | }; | |
| 260 | 939 | const auto prefix = [&plan, &item, &context] { | |
| 261 |
3/4✓ Branch 5 → 6 taken 27 times.
✓ Branch 5 → 9 taken 608 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 27 times.
|
635 | return item.parent.isEmpty() || item.context.isEmpty() || plan.domain != QLatin1String("ical") |
| 262 |
2/2✓ Branch 3 → 4 taken 635 times.
✓ Branch 3 → 9 taken 304 times.
|
939 | ? QString() |
| 263 |
8/14✓ Branch 13 → 14 taken 27 times.
✓ Branch 14 → 15 taken 27 times.
✓ Branch 16 → 17 taken 27 times.
✓ Branch 16 → 18 taken 912 times.
✓ Branch 18 → 19 taken 27 times.
✓ Branch 18 → 20 taken 912 times.
✓ Branch 20 → 21 taken 27 times.
✓ Branch 20 → 22 taken 912 times.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 26 not taken.
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 34 not taken.
|
2817 | : ConflictValueText::componentLabel(plan, item, context) + QStringLiteral(" — "); |
| 264 | 62665 | }; | |
| 265 | const bool groupConflict = | ||
| 266 |
9/11✓ Branch 32 → 33 taken 20956 times.
✓ Branch 32 → 39 taken 41709 times.
✓ Branch 34 → 35 taken 20896 times.
✓ Branch 34 → 39 taken 60 times.
✓ Branch 35 → 36 taken 20896 times.
✓ Branch 37 → 38 taken 110 times.
✓ Branch 37 → 39 taken 20786 times.
✓ Branch 40 → 41 taken 20896 times.
✓ Branch 40 → 42 taken 41769 times.
✗ Branch 260 → 261 not taken.
✗ Branch 260 → 262 not taken.
|
62665 | !item.group.isEmpty() && !plan.groupSeparated(item.group) && conflictGroups.contains(scopeKey(item)); |
| 267 | 62665 | Row row; | |
| 268 |
2/2✓ Branch 42 → 43 taken 110 times.
✓ Branch 42 → 87 taken 62555 times.
|
62665 | if (groupConflict) { |
| 269 |
3/3✓ Branch 44 → 45 taken 8 times.
✓ Branch 44 → 46 taken 102 times.
✓ Branch 47 → 48 taken 110 times.
|
110 | collect(crossParent ? byCrossGroup.value(item.group) : byParent.value(item.parent), |
| 270 | 829 | [&item](const Merge::Item &other) { return other.group == item.group; }); | |
| 271 |
1/1✓ Branch 53 → 54 taken 110 times.
|
110 | row.id = QStringLiteral("group:%1:%2").arg(item.parent, item.group); |
| 272 | 110 | row.kind = QStringLiteral("field"); | |
| 273 | 110 | row.group = item.group; | |
| 274 | 110 | row.separable = members.size() > 1; | |
| 275 |
3/3✓ Branch 66 → 67 taken 110 times.
✓ Branch 67 → 68 taken 110 times.
✓ Branch 68 → 69 taken 110 times.
|
110 | row.label = prefix() + ConflictValueText::groupLabel(item.group); |
| 276 |
4/4✓ Branch 73 → 74 taken 110 times.
✓ Branch 74 → 75 taken 110 times.
✓ Branch 85 → 76 taken 219 times.
✓ Branch 85 → 86 taken 110 times.
|
329 | for (const Merge::Item *member : members) |
| 277 |
4/4✓ Branch 77 → 78 taken 16 times.
✓ Branch 77 → 83 taken 203 times.
✓ Branch 78 → 79 taken 8 times.
✓ Branch 78 → 83 taken 8 times.
|
219 | if (crossParent && member->kind == Merge::Kind::Component) |
| 278 |
1/1✓ Branch 79 → 80 taken 8 times.
|
8 | row.label = ConflictValueText::componentLabel(plan, *member, context); |
| 279 |
1/1✓ Branch 86 → 220 taken 110 times.
|
110 | finishRow(&row, plan, members, context); |
| 280 |
2/2✓ Branch 87 → 88 taken 189 times.
✓ Branch 87 → 156 taken 62366 times.
|
62555 | } else if (item.kind == Merge::Kind::SetValue) { |
| 281 |
1/1✓ Branch 90 → 91 taken 189 times.
|
189 | collect(byParent.value(item.parent), [&item](const Merge::Item &other) { |
| 282 |
6/6✓ Branch 2 → 3 taken 589 times.
✓ Branch 2 → 10 taken 744 times.
✓ Branch 4 → 5 taken 363 times.
✓ Branch 4 → 10 taken 226 times.
✓ Branch 6 → 7 taken 18 times.
✓ Branch 6 → 9 taken 345 times.
|
1714 | return other.kind == Merge::Kind::SetValue && other.name == item.name && |
| 283 |
1/2✓ Branch 8 → 9 taken 18 times.
✗ Branch 8 → 10 not taken.
|
1714 | (other.group.isEmpty() || other.group == item.group); |
| 284 | }); | ||
| 285 | 189 | bool changed = false; | |
| 286 |
4/4✓ Branch 93 → 94 taken 189 times.
✓ Branch 94 → 95 taken 189 times.
✓ Branch 103 → 96 taken 363 times.
✓ Branch 103 → 104 taken 189 times.
|
552 | for (const Merge::Item *member : members) |
| 287 |
4/4✓ Branch 97 → 98 taken 258 times.
✓ Branch 97 → 99 taken 105 times.
✓ Branch 98 → 99 taken 175 times.
✓ Branch 98 → 100 taken 83 times.
|
363 | changed = changed || member->state != Merge::State::Same; |
| 288 |
2/2✓ Branch 104 → 105 taken 14 times.
✓ Branch 104 → 106 taken 175 times.
|
189 | if (!changed) |
| 289 | 14 | continue; | |
| 290 |
1/1✓ Branch 109 → 110 taken 175 times.
|
175 | row.id = QStringLiteral("list:%1:%2").arg(item.parent, item.name); |
| 291 | 175 | row.kind = QStringLiteral("list"); | |
| 292 |
3/3✓ Branch 120 → 121 taken 175 times.
✓ Branch 121 → 122 taken 175 times.
✓ Branch 122 → 123 taken 175 times.
|
175 | row.label = prefix() + ConflictValueText::label(plan, item); |
| 293 |
1/1✓ Branch 127 → 128 taken 175 times.
|
175 | finishRow(&row, plan, members, context); |
| 294 |
4/4✓ Branch 128 → 129 taken 175 times.
✓ Branch 129 → 130 taken 175 times.
✓ Branch 154 → 131 taken 349 times.
✓ Branch 154 → 155 taken 175 times.
|
524 | for (const Merge::Item *member : members) { |
| 295 | 349 | bool included = false; | |
| 296 |
1/1✓ Branch 132 → 133 taken 349 times.
|
349 | Merge::resultText(*member, &included); |
| 297 |
2/2✓ Branch 134 → 135 taken 200 times.
✓ Branch 134 → 136 taken 149 times.
|
498 | const ConflictValueText::Side side = member->local.present ? ConflictValueText::Side::Local |
| 298 |
2/2✓ Branch 136 → 137 taken 129 times.
✓ Branch 136 → 138 taken 20 times.
|
149 | : member->server.present ? ConflictValueText::Side::Server |
| 299 | : ConflictValueText::Side::Base; | ||
| 300 | 349 | row.values.append({member->id, ConflictValueText::value(plan, *member, side, context), member->local.present, | |
| 301 | 349 | member->server.present, member->base.present, | |
| 302 |
3/3✓ Branch 143 → 144 taken 301 times.
✓ Branch 144 → 145 taken 294 times.
✓ Branch 144 → 146 taken 7 times.
|
698 | included && !Merge::itemOpen(plan, *member), QString::fromLatin1(Merge::stateName(member->state))}); |
| 303 | } | ||
| 304 | } else { | ||
| 305 |
1/1✓ Branch 156 → 157 taken 62366 times.
|
62366 | handled.insert(item.id); |
| 306 |
2/2✓ Branch 157 → 158 taken 61548 times.
✓ Branch 157 → 159 taken 818 times.
|
62366 | if (item.state == Merge::State::Same) |
| 307 | 61548 | continue; | |
| 308 |
1/1✓ Branch 159 → 160 taken 818 times.
|
818 | members = {&item}; |
| 309 |
2/2✓ Branch 160 → 161 taken 125 times.
✓ Branch 160 → 172 taken 693 times.
|
818 | if (item.kind == Merge::Kind::Text) { |
| 310 |
1/1✓ Branch 161 → 162 taken 125 times.
|
125 | row = textRow(plan, item, context); |
| 311 |
3/3✓ Branch 164 → 165 taken 125 times.
✓ Branch 165 → 166 taken 125 times.
✓ Branch 166 → 167 taken 125 times.
|
125 | row.label = prefix() + ConflictValueText::label(plan, item); |
| 312 | } else { | ||
| 313 | 693 | row.id = item.id; | |
| 314 |
2/2✓ Branch 173 → 174 taken 140 times.
✓ Branch 173 → 177 taken 553 times.
|
2219 | row.kind = item.kind == Merge::Kind::Component ? QStringLiteral("component") |
| 315 |
4/4✓ Branch 177 → 178 taken 24 times.
✓ Branch 177 → 181 taken 529 times.
✓ Branch 204 → 205 taken 140 times.
✓ Branch 204 → 206 taken 553 times.
|
1246 | : item.kind == Merge::Kind::Deletion ? QStringLiteral("deletion") |
| 316 |
4/4✓ Branch 181 → 182 taken 12 times.
✓ Branch 181 → 185 taken 517 times.
✓ Branch 202 → 203 taken 24 times.
✓ Branch 202 → 204 taken 669 times.
|
1222 | : item.kind == Merge::Kind::Order ? QStringLiteral("order") |
| 317 |
4/4✓ Branch 187 → 188 taken 20 times.
✓ Branch 187 → 191 taken 497 times.
✓ Branch 200 → 201 taken 12 times.
✓ Branch 200 → 202 taken 681 times.
|
1210 | : item.name == QLatin1String("PHOTO") ? QStringLiteral("photo") |
| 318 |
4/4✓ Branch 196 → 197 taken 497 times.
✓ Branch 196 → 198 taken 196 times.
✓ Branch 198 → 199 taken 20 times.
✓ Branch 198 → 200 taken 673 times.
|
1386 | : QStringLiteral("field"); |
| 319 |
2/2✓ Branch 207 → 208 taken 24 times.
✓ Branch 207 → 210 taken 529 times.
|
553 | row.label = item.kind == Merge::Kind::Component || item.kind == Merge::Kind::Deletion |
| 320 |
4/4✓ Branch 206 → 207 taken 553 times.
✓ Branch 206 → 208 taken 140 times.
✓ Branch 208 → 209 taken 164 times.
✓ Branch 212 → 213 taken 529 times.
|
1939 | ? ConflictValueText::componentLabel(plan, item, context) |
| 321 |
6/10✓ Branch 210 → 211 taken 529 times.
✓ Branch 211 → 212 taken 529 times.
✓ Branch 215 → 216 taken 529 times.
✓ Branch 215 → 217 taken 164 times.
✓ Branch 217 → 218 taken 529 times.
✓ Branch 217 → 219 taken 164 times.
✗ Branch 333 → 334 not taken.
✗ Branch 333 → 335 not taken.
✗ Branch 337 → 338 not taken.
✗ Branch 337 → 339 not taken.
|
1915 | : prefix() + ConflictValueText::label(plan, item); |
| 322 |
1/1✓ Branch 219 → 220 taken 693 times.
|
693 | finishRow(&row, plan, members, context); |
| 323 | } | ||
| 324 | } | ||
| 325 |
6/6✓ Branch 220 → 221 taken 421 times.
✓ Branch 220 → 224 taken 682 times.
✓ Branch 229 → 230 taken 682 times.
✓ Branch 229 → 231 taken 421 times.
✓ Branch 231 → 232 taken 421 times.
✓ Branch 231 → 233 taken 682 times.
|
2206 | row.section = row.conflict ? QStringLiteral("question") : QStringLiteral("combined"); |
| 326 |
1/1✓ Branch 233 → 234 taken 1103 times.
|
1103 | rows.append(row); |
| 327 | 124227 | } | |
| 328 |
7/7✓ Branch 2 → 3 taken 217 times.
✓ Branch 2 → 5 taken 432 times.
✓ Branch 3 → 4 taken 70 times.
✓ Branch 3 → 5 taken 147 times.
✓ Branch 247 → 248 taken 674 times.
✓ Branch 248 → 249 taken 674 times.
✓ Branch 249 → 250 taken 674 times.
|
1323 | std::stable_sort(rows.begin(), rows.end(), [](const Row &a, const Row &b) { return a.conflict && !b.conflict; }); |
| 329 | 674 | return rows; | |
| 330 | 2070 | } | |
| 331 | |||
| 332 | 83 | const Row *find(const QList<Row> &rows, const QString &id) { | |
| 333 |
2/2✓ Branch 10 → 4 taken 99 times.
✓ Branch 10 → 11 taken 9 times.
|
108 | for (const Row &row : rows) |
| 334 |
2/2✓ Branch 6 → 7 taken 74 times.
✓ Branch 6 → 8 taken 25 times.
|
99 | if (row.id == id) |
| 335 | 74 | return &row; | |
| 336 | 9 | return nullptr; | |
| 337 | } | ||
| 338 | |||
| 339 | } // namespace ConflictRows | ||
| 340 |