data/ContactIndex.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "ContactIndex.h" | ||
| 2 | |||
| 3 | #include <QCryptographicHash> | ||
| 4 | |||
| 5 | namespace ContactIndex { | ||
| 6 | |||
| 7 | 98048 | QString displayName(const ContactCard &card) { | |
| 8 |
3/3✓ Branch 2 → 3 taken 98048 times.
✓ Branch 5 → 6 taken 98039 times.
✓ Branch 5 → 8 taken 9 times.
|
98048 | if (!card.formattedName.trimmed().isEmpty()) |
| 9 |
1/1✓ Branch 6 → 7 taken 98039 times.
|
98039 | return card.formattedName.simplified(); |
| 10 | const QString composed = | ||
| 11 |
2/4✓ Branch 21 → 22 taken 45 times.
✓ Branch 21 → 23 taken 9 times.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 51 not taken.
|
54 | QStringList{card.name.prefix, card.name.given, card.name.additional, card.name.family, card.name.suffix} |
| 12 |
1/1✓ Branch 16 → 17 taken 9 times.
|
18 | .join(QLatin1Char(' ')) |
| 13 |
1/1✓ Branch 17 → 18 taken 9 times.
|
9 | .simplified(); |
| 14 |
2/2✓ Branch 24 → 25 taken 8 times.
✓ Branch 24 → 26 taken 1 time.
|
9 | if (!composed.isEmpty()) |
| 15 | 8 | return composed; | |
| 16 |
2/3✓ Branch 26 → 27 taken 1 time.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 32 not taken.
|
1 | if (!card.organization.trimmed().isEmpty()) |
| 17 |
1/1✓ Branch 30 → 31 taken 1 time.
|
1 | return card.organization.simplified(); |
| 18 | ✗ | if (!card.emails.isEmpty()) | |
| 19 | ✗ | return card.emails.first().value.trimmed(); | |
| 20 | ✗ | return {}; | |
| 21 | 18 | } | |
| 22 | |||
| 23 | 30499 | QString familyFirstName(const ContactCard &card) { | |
| 24 |
3/3✓ Branch 2 → 3 taken 30499 times.
✓ Branch 5 → 6 taken 22450 times.
✓ Branch 5 → 8 taken 8049 times.
|
30499 | if (card.name.family.trimmed().isEmpty()) |
| 25 |
1/1✓ Branch 6 → 7 taken 22450 times.
|
22450 | return displayName(card); |
| 26 |
3/3✓ Branch 10 → 11 taken 8049 times.
✓ Branch 11 → 12 taken 8049 times.
✓ Branch 12 → 13 taken 8049 times.
|
8049 | const QString given = (card.name.given + QLatin1Char(' ') + card.name.additional).simplified(); |
| 27 |
14/22✓ Branch 16 → 17 taken 5822 times.
✓ Branch 16 → 18 taken 2227 times.
✓ Branch 17 → 24 taken 5822 times.
✓ Branch 21 → 22 taken 2227 times.
✓ Branch 22 → 23 taken 2227 times.
✓ Branch 23 → 24 taken 2227 times.
✓ Branch 25 → 26 taken 2227 times.
✓ Branch 25 → 27 taken 5822 times.
✓ Branch 27 → 28 taken 2227 times.
✓ Branch 27 → 29 taken 5822 times.
✓ Branch 29 → 30 taken 2227 times.
✓ Branch 29 → 31 taken 5822 times.
✓ Branch 31 → 32 taken 2227 times.
✓ Branch 31 → 33 taken 5822 times.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 47 not taken.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 51 not taken.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 59 not taken.
|
10276 | return given.isEmpty() ? card.name.family.simplified() : card.name.family.simplified() + QStringLiteral(", ") + given; |
| 28 | 8049 | } | |
| 29 | |||
| 30 | 273406 | QString foldForSort(const QString &text) { | |
| 31 |
1/1✓ Branch 2 → 3 taken 273406 times.
|
273406 | const QString decomposed = text.normalized(QString::NormalizationForm_KD); |
| 32 | 273406 | QString folded; | |
| 33 |
1/1✓ Branch 4 → 5 taken 273406 times.
|
273406 | folded.reserve(decomposed.size()); |
| 34 |
2/2✓ Branch 59 → 7 taken 17012433 times.
✓ Branch 59 → 60 taken 273406 times.
|
17285839 | for (const QChar c : decomposed) { |
| 35 |
7/8✓ Branch 8 → 9 taken 16930825 times.
✓ Branch 8 → 13 taken 81608 times.
✓ Branch 10 → 11 taken 16930799 times.
✓ Branch 10 → 13 taken 26 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 16930799 times.
✓ Branch 15 → 16 taken 81634 times.
✓ Branch 15 → 17 taken 16930799 times.
|
33943232 | if (c.category() == QChar::Mark_NonSpacing || c.category() == QChar::Mark_SpacingCombining || |
| 36 | 16930799 | c.category() == QChar::Mark_Enclosing) | |
| 37 | 81634 | continue; | |
| 38 |
2/2✓ Branch 19 → 20 taken 11 times.
✓ Branch 19 → 27 taken 16930788 times.
|
16930799 | if (c == QChar(0x00DF)) { // ß |
| 39 |
1/1✓ Branch 23 → 24 taken 11 times.
|
11 | folded += QStringLiteral("ss"); |
| 40 | 11 | continue; | |
| 41 | } | ||
| 42 | // Letters without a decomposition that should sort with their base letter. | ||
| 43 |
4/6✓ Branch 28 → 29 taken 2 times.
✓ Branch 28 → 33 taken 320 times.
✓ Branch 28 → 37 taken 15 times.
✗ Branch 28 → 41 not taken.
✗ Branch 28 → 48 not taken.
✓ Branch 28 → 55 taken 16930451 times.
|
16930788 | switch (c.unicode()) { |
| 44 |
1/1✓ Branch 31 → 32 taken 2 times.
|
2 | case 0x00F8: case 0x00D8: folded += QLatin1Char('o'); continue; // ø |
| 45 |
1/1✓ Branch 35 → 36 taken 320 times.
|
320 | case 0x0131: folded += QLatin1Char('i'); continue; // dotless ı |
| 46 |
1/1✓ Branch 39 → 40 taken 15 times.
|
15 | case 0x0142: case 0x0141: folded += QLatin1Char('l'); continue; // ł |
| 47 | ✗ | case 0x00E6: case 0x00C6: folded += QStringLiteral("ae"); continue; | |
| 48 | ✗ | case 0x0153: case 0x0152: folded += QStringLiteral("oe"); continue; | |
| 49 | 16930451 | default: break; | |
| 50 | } | ||
| 51 |
1/1✓ Branch 57 → 58 taken 16930451 times.
|
16930451 | folded += c.toCaseFolded(); |
| 52 | } | ||
| 53 | // Surrounding quotes, brackets and dashes do not decide the order. | ||
| 54 | 273406 | int start = 0; | |
| 55 |
6/6✓ Branch 63 → 64 taken 265802 times.
✓ Branch 63 → 68 taken 27297 times.
✓ Branch 66 → 67 taken 19693 times.
✓ Branch 66 → 68 taken 246109 times.
✓ Branch 69 → 61 taken 19693 times.
✓ Branch 69 → 70 taken 273406 times.
|
293099 | while (start < folded.size() && !folded.at(start).isLetterOrNumber()) |
| 56 | 19693 | ++start; | |
| 57 | 273406 | int end = int(folded.size()); | |
| 58 |
6/6✓ Branch 73 → 74 taken 418619 times.
✓ Branch 73 → 78 taken 27297 times.
✓ Branch 76 → 77 taken 172510 times.
✓ Branch 76 → 78 taken 246109 times.
✓ Branch 79 → 72 taken 172510 times.
✓ Branch 79 → 80 taken 273406 times.
|
445916 | while (end > start && !folded.at(end - 1).isLetterOrNumber()) |
| 59 | 172510 | --end; | |
| 60 |
2/2✓ Branch 80 → 81 taken 273406 times.
✓ Branch 81 → 82 taken 273406 times.
|
546812 | return folded.mid(start, end - start).simplified(); |
| 61 | 273406 | } | |
| 62 | |||
| 63 | 36445 | QString sectionOf(const QString &foldedKey) { | |
| 64 |
1/2✗ Branch 3 → 4 not taken.
✓ Branch 3 → 9 taken 36445 times.
|
36445 | if (foldedKey.isEmpty()) |
| 65 | ✗ | return QStringLiteral("#"); | |
| 66 | 36445 | const QChar first = foldedKey.at(0); | |
| 67 |
5/6✓ Branch 14 → 15 taken 36440 times.
✓ Branch 14 → 21 taken 5 times.
✓ Branch 19 → 20 taken 36440 times.
✗ Branch 19 → 21 not taken.
✓ Branch 22 → 23 taken 36440 times.
✓ Branch 22 → 26 taken 5 times.
|
36445 | if (first >= QLatin1Char('a') && first <= QLatin1Char('z')) |
| 68 |
1/1✓ Branch 24 → 25 taken 36440 times.
|
36440 | return QString(first.toUpper()); |
| 69 | 5 | return QStringLiteral("#"); | |
| 70 | } | ||
| 71 | |||
| 72 |
2/2✓ Branch 2 → 3 taken 31848 times.
✓ Branch 3 → 4 taken 31848 times.
|
31848 | QString addressKey(const QString &address) { return address.trimmed().toLower(); } |
| 73 | |||
| 74 | 1520 | QString phoneDigits(const QString &phone) { | |
| 75 | 1520 | QString digits; | |
| 76 |
2/2✓ Branch 8 → 4 taken 22020 times.
✓ Branch 8 → 9 taken 1520 times.
|
23540 | for (const QChar c : phone) |
| 77 |
2/2✓ Branch 5 → 6 taken 17405 times.
✓ Branch 5 → 7 taken 4615 times.
|
22020 | if (c.isDigit()) |
| 78 |
1/1✓ Branch 6 → 7 taken 17405 times.
|
17405 | digits += c; |
| 79 | 1520 | return digits; | |
| 80 | ✗ | } | |
| 81 | |||
| 82 | 30506 | QString searchText(const ContactCard &card) { | |
| 83 | 91518 | QStringList parts{displayName(card), card.nickname, card.organization, card.department, | |
| 84 |
2/4✓ Branch 12 → 13 taken 244048 times.
✓ Branch 12 → 14 taken 30506 times.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 86 not taken.
|
274554 | card.title, card.name.given, card.name.family, card.note}; |
| 85 |
2/2✓ Branch 20 → 16 taken 29943 times.
✓ Branch 20 → 21 taken 30506 times.
|
60449 | for (const ContactValue &email : card.emails) |
| 86 |
1/1✓ Branch 17 → 18 taken 29943 times.
|
29943 | parts << email.value; |
| 87 |
2/2✓ Branch 30 → 23 taken 1519 times.
✓ Branch 30 → 31 taken 30506 times.
|
32025 | for (const ContactValue &phone : card.phones) |
| 88 |
3/3✓ Branch 24 → 25 taken 1519 times.
✓ Branch 25 → 26 taken 1519 times.
✓ Branch 26 → 27 taken 1519 times.
|
1519 | parts << phone.value << phoneDigits(phone.value); |
| 89 |
2/2✓ Branch 39 → 33 taken 2215 times.
✓ Branch 39 → 40 taken 30506 times.
|
32721 | for (const ContactAddress &address : card.addresses) |
| 90 |
2/2✓ Branch 34 → 35 taken 2215 times.
✓ Branch 35 → 36 taken 2215 times.
|
2215 | parts << address.oneLine(); |
| 91 |
1/1✓ Branch 40 → 41 taken 30506 times.
|
30506 | parts << card.categories; |
| 92 | // Sprint 103 (S103.1.4): names in relationships and introductions, where | ||
| 93 | // and when we met, services and handles, interests and the birthplace. | ||
| 94 |
2/2✓ Branch 48 → 43 taken 529 times.
✓ Branch 48 → 49 taken 30506 times.
|
31035 | for (const ContactRelation &relation : card.relations) |
| 95 |
2/2✓ Branch 44 → 45 taken 529 times.
✓ Branch 45 → 46 taken 529 times.
|
529 | parts << relation.targetName << relation.label; |
| 96 |
2/2✓ Branch 55 → 51 taken 105 times.
✓ Branch 55 → 56 taken 30506 times.
|
30611 | for (const ContactPersonRef &via : card.met.via) |
| 97 |
1/1✓ Branch 52 → 53 taken 105 times.
|
105 | parts << via.name; |
| 98 |
2/2✓ Branch 56 → 57 taken 30506 times.
✓ Branch 57 → 58 taken 30506 times.
|
30506 | parts << card.met.place << card.met.note; |
| 99 |
2/2✓ Branch 58 → 59 taken 127 times.
✓ Branch 58 → 63 taken 30379 times.
|
30506 | if (card.met.date.year > 0) |
| 100 |
2/2✓ Branch 59 → 60 taken 127 times.
✓ Branch 60 → 61 taken 127 times.
|
127 | parts << QString::number(card.met.date.year); |
| 101 |
2/2✓ Branch 71 → 65 taken 189 times.
✓ Branch 71 → 72 taken 30506 times.
|
30695 | for (const ContactSocial &social : card.social) |
| 102 |
3/3✓ Branch 66 → 67 taken 189 times.
✓ Branch 67 → 68 taken 189 times.
✓ Branch 68 → 69 taken 189 times.
|
189 | parts << social.service << social.user << social.value; |
| 103 |
2/2✓ Branch 72 → 73 taken 30506 times.
✓ Branch 73 → 74 taken 30506 times.
|
30506 | parts << card.interests << card.birthplace; |
| 104 |
2/2✓ Branch 76 → 77 taken 30506 times.
✓ Branch 77 → 78 taken 30506 times.
|
61012 | return foldForSort(parts.join(QLatin1Char(' '))); |
| 105 | 61012 | } | |
| 106 | |||
| 107 | 35537 | QString primaryAddress(const ContactCard &card) { | |
| 108 |
2/2✓ Branch 18 → 4 taken 29977 times.
✓ Branch 18 → 19 taken 35535 times.
|
65512 | for (const ContactValue &email : card.emails) |
| 109 |
8/11✓ Branch 5 → 6 taken 2 times.
✓ Branch 5 → 10 taken 29975 times.
✓ Branch 6 → 7 taken 2 times.
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 10 not taken.
✓ Branch 11 → 12 taken 2 times.
✓ Branch 11 → 13 taken 29975 times.
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 16 taken 29975 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
|
29977 | if (email.preferred && !email.value.trimmed().isEmpty()) |
| 110 |
1/1✓ Branch 14 → 15 taken 2 times.
|
2 | return email.value.trimmed(); |
| 111 |
2/2✓ Branch 30 → 21 taken 29820 times.
✓ Branch 30 → 31 taken 5715 times.
|
35535 | for (const ContactValue &email : card.emails) |
| 112 |
2/3✓ Branch 22 → 23 taken 29820 times.
✓ Branch 25 → 26 taken 29820 times.
✗ Branch 25 → 28 not taken.
|
29820 | if (!email.value.trimmed().isEmpty()) |
| 113 |
1/1✓ Branch 26 → 27 taken 29820 times.
|
29820 | return email.value.trimmed(); |
| 114 | 5715 | return {}; | |
| 115 | } | ||
| 116 | |||
| 117 | 30498 | QString primaryPhone(const ContactCard &card) { | |
| 118 |
2/2✓ Branch 18 → 4 taken 1519 times.
✓ Branch 18 → 19 taken 30498 times.
|
32017 | for (const ContactValue &phone : card.phones) |
| 119 |
3/11✗ Branch 5 → 6 not taken.
✓ Branch 5 → 10 taken 1519 times.
✗ Branch 6 → 7 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 1519 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 1519 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
|
1519 | if (phone.preferred && !phone.value.trimmed().isEmpty()) |
| 120 | ✗ | return phone.value.trimmed(); | |
| 121 |
2/2✓ Branch 30 → 21 taken 1484 times.
✓ Branch 30 → 31 taken 29014 times.
|
30498 | for (const ContactValue &phone : card.phones) |
| 122 |
2/3✓ Branch 22 → 23 taken 1484 times.
✓ Branch 25 → 26 taken 1484 times.
✗ Branch 25 → 28 not taken.
|
1484 | if (!phone.value.trimmed().isEmpty()) |
| 123 |
1/1✓ Branch 26 → 27 taken 1484 times.
|
1484 | return phone.value.trimmed(); |
| 124 | 29014 | return {}; | |
| 125 | } | ||
| 126 | |||
| 127 | 30498 | QString primaryLocality(const ContactCard &card) { | |
| 128 |
2/2✓ Branch 18 → 4 taken 2213 times.
✓ Branch 18 → 19 taken 30497 times.
|
32710 | for (const ContactAddress &address : card.addresses) |
| 129 |
8/11✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 10 taken 2212 times.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
✓ Branch 11 → 12 taken 1 time.
✓ Branch 11 → 13 taken 2212 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 16 taken 2212 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
|
2213 | if (address.preferred && !address.locality.trimmed().isEmpty()) |
| 130 |
1/1✓ Branch 14 → 15 taken 1 time.
|
1 | return address.locality.trimmed(); |
| 131 |
2/2✓ Branch 30 → 21 taken 2211 times.
✓ Branch 30 → 31 taken 28304 times.
|
30515 | for (const ContactAddress &address : card.addresses) |
| 132 |
3/3✓ Branch 22 → 23 taken 2211 times.
✓ Branch 25 → 26 taken 2193 times.
✓ Branch 25 → 28 taken 18 times.
|
2211 | if (!address.locality.trimmed().isEmpty()) |
| 133 |
1/1✓ Branch 26 → 27 taken 2193 times.
|
2193 | return address.locality.trimmed(); |
| 134 | 28304 | return {}; | |
| 135 | } | ||
| 136 | |||
| 137 | 9319 | QString initials(const ContactCard &card) { | |
| 138 |
1/1✓ Branch 2 → 3 taken 9319 times.
|
9319 | QString given = card.name.given.trimmed(); |
| 139 |
1/1✓ Branch 3 → 4 taken 9319 times.
|
9319 | QString family = card.name.family.trimmed(); |
| 140 |
6/6✓ Branch 5 → 6 taken 8879 times.
✓ Branch 5 → 9 taken 440 times.
✓ Branch 7 → 8 taken 8805 times.
✓ Branch 7 → 9 taken 74 times.
✓ Branch 10 → 11 taken 8805 times.
✓ Branch 10 → 29 taken 514 times.
|
9319 | if (given.isEmpty() && family.isEmpty()) { |
| 141 |
2/2✓ Branch 11 → 12 taken 8805 times.
✓ Branch 15 → 16 taken 8805 times.
|
8805 | const QStringList words = displayName(card).split(QLatin1Char(' '), Qt::SkipEmptyParts); |
| 142 |
1/1✓ Branch 17 → 18 taken 8805 times.
|
8805 | given = words.value(0); |
| 143 |
2/2✓ Branch 21 → 22 taken 7647 times.
✓ Branch 21 → 24 taken 1158 times.
|
8805 | family = words.size() > 1 ? words.last() : QString(); |
| 144 | 8805 | } | |
| 145 | 9319 | QString result; | |
| 146 |
2/2✓ Branch 43 → 33 taken 18638 times.
✓ Branch 43 → 44 taken 9319 times.
|
46595 | for (const QString &word : {given, family}) |
| 147 |
2/2✓ Branch 41 → 35 taken 17398 times.
✓ Branch 41 → 42 taken 1240 times.
|
18638 | for (const QChar c : word) |
| 148 |
1/2✓ Branch 36 → 37 taken 17398 times.
✗ Branch 36 → 40 not taken.
|
17398 | if (c.isLetterOrNumber()) { |
| 149 |
1/1✓ Branch 38 → 39 taken 17398 times.
|
17398 | result += c.toUpper(); |
| 150 | 17398 | break; | |
| 151 | 27957 | } | |
| 152 |
1/1✓ Branch 50 → 51 taken 9319 times.
|
18638 | return result.left(2); |
| 153 | 9319 | } | |
| 154 | |||
| 155 | 11222 | int avatarColorIndex(const QString &uid) { | |
| 156 |
2/2✓ Branch 2 → 3 taken 11222 times.
✓ Branch 4 → 5 taken 11222 times.
|
11222 | const QByteArray hash = QCryptographicHash::hash(uid.toUtf8(), QCryptographicHash::Sha1); |
| 157 | 22444 | return static_cast<unsigned char>(hash.at(0)) % 8; | |
| 158 | 11222 | } | |
| 159 | |||
| 160 | } // namespace ContactIndex | ||
| 161 |