presentation/MailPresentationModel.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "MailPresentationModel.h" | ||
| 2 | #include <QLocale> | ||
| 3 | #include "WorkspaceState.h" | ||
| 4 | #include "ui/LabelDelegate.h" | ||
| 5 | #include "service/ImapResponseParser.h" | ||
| 6 | |||
| 7 | 972 | MailPresentationModel::MailPresentationModel(MailListModel *source, QString accountId, QObject *parent) | |
| 8 | 972 | : MailFilterProxyModel(parent), m_headers(source), m_accountId(std::move(accountId)) { | |
| 9 |
1/1✓ Branch 13 → 14 taken 972 times.
|
972 | setSourceModel(source); |
| 10 | // Source roles describe widget columns; Quick properties span the entire row. | ||
| 11 | 972 | connect(source, &QAbstractItemModel::dataChanged, this, | |
| 12 |
1/1✓ Branch 14 → 15 taken 972 times.
|
972 | [this](const QModelIndex &first, const QModelIndex &last, const QList<int> &sourceRoles) { |
| 13 | 740 | QList<int> quickRoles; | |
| 14 |
2/2✓ Branch 3 → 4 taken 591 times.
✓ Branch 3 → 5 taken 149 times.
|
740 | if (sourceRoles.contains(MailListModel::FlagsRole)) |
| 15 |
1/1✓ Branch 4 → 26 taken 591 times.
|
591 | quickRoles = {Unread, Starred, Answered}; |
| 16 |
2/2✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 9 taken 148 times.
|
149 | else if (sourceRoles.contains(MailListModel::HasAttachmentsRole)) |
| 17 |
1/1✓ Branch 7 → 8 taken 1 time.
|
1 | quickRoles = {Attachment}; |
| 18 |
2/6✗ Branch 10 → 11 not taken.
✓ Branch 10 → 14 taken 148 times.
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 14 not taken.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 18 taken 148 times.
|
148 | else if (first.column() == MailListModel::Suggestion && |
| 19 | ✗ | last.column() == MailListModel::Suggestion) | |
| 20 | ✗ | quickRoles = {Suggestion}; | |
| 21 |
5/6✓ Branch 19 → 20 taken 90 times.
✓ Branch 19 → 23 taken 58 times.
✓ Branch 21 → 22 taken 90 times.
✗ Branch 21 → 23 not taken.
✓ Branch 24 → 25 taken 90 times.
✓ Branch 24 → 26 taken 58 times.
|
238 | else if (first.column() == MailListModel::Subject && |
| 22 | 90 | last.column() == MailListModel::Subject) | |
| 23 |
1/1✓ Branch 25 → 26 taken 90 times.
|
90 | quickRoles = {Subject, Folder}; |
| 24 |
2/2✓ Branch 41 → 27 taken 13316 times.
✓ Branch 41 → 42 taken 740 times.
|
14056 | for (int row = first.row(); row <= last.row(); ++row) { |
| 25 |
2/2✓ Branch 28 → 29 taken 13316 times.
✓ Branch 29 → 30 taken 13316 times.
|
13316 | const auto proxy = mapFromSource(m_headers->index(row, 0)); |
| 26 |
4/5✓ Branch 31 → 32 taken 13316 times.
✗ Branch 31 → 39 not taken.
✓ Branch 34 → 35 taken 13316 times.
✓ Branch 36 → 37 taken 13316 times.
✓ Branch 37 → 38 taken 13316 times.
|
13316 | if (proxy.isValid()) emit dataChanged(proxy, index(proxy.row(), columnCount() - 1), quickRoles); |
| 27 | } | ||
| 28 | 740 | }); | |
| 29 |
1/1✓ Branch 16 → 17 taken 972 times.
|
972 | connect(source, &QObject::destroyed, this, [this] { m_headers = nullptr; }); |
| 30 | 972 | } | |
| 31 | 2486 | QHash<int, QByteArray> MailPresentationModel::roleNames() const { | |
| 32 | ✗ | return {{Identity, "mailIdentity"}, {Subject, "subject"}, {Sender, "sender"}, | |
| 33 | ✗ | {Date, "dateText"}, {Unread, "unread"}, {Starred, "starred"}, | |
| 34 | ✗ | {Labels, "labels"}, {Attachment, "hasAttachment"}, {Selected, "mailSelected"}, {Folder, "folderBadge"}, {Suggestion, "folderSuggestion"}, | |
| 35 | ✗ | {Depth, "depth"}, {ThreadCount, "threadCount"}, {HasChildren, "threadHasChildren"}, {Expanded, "threadExpanded"}, | |
| 36 | ✗ | {LabelChips, "labelChips"}, {OpenTask, "hasOpenTask"}, {RuleMatch, "ruleMatched"}, | |
| 37 | ✗ | {Recipient, "recipient"}, {SizeText, "sizeText"}, {Period, "period"}, | |
| 38 |
2/4✓ Branch 27 → 28 taken 57178 times.
✓ Branch 27 → 29 taken 2486 times.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 34 not taken.
|
59664 | {MatchedInText, "matchedInText"}, {Answered, "answered"}}; |
| 39 | 2486 | } | |
| 40 | 793 | void MailPresentationModel::setAccountId(const QString &accountId) { | |
| 41 |
2/2✓ Branch 3 → 4 taken 15 times.
✓ Branch 3 → 5 taken 778 times.
|
793 | if (m_accountId == accountId) return; |
| 42 | 778 | m_accountId = accountId; | |
| 43 |
9/9✓ Branch 7 → 8 taken 778 times.
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 21 taken 777 times.
✓ Branch 9 → 10 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 14 → 15 taken 1 time.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 17 → 18 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
|
778 | if (rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1), {Identity}); |
| 44 | } | ||
| 45 | 931474 | QVariant MailPresentationModel::data(const QModelIndex &index, int role) const { | |
| 46 |
3/6✓ Branch 2 → 3 taken 931474 times.
✗ Branch 2 → 5 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 931474 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 931474 times.
|
931474 | if (!m_headers || !index.isValid()) return {}; |
| 47 |
2/2✓ Branch 9 → 10 taken 931474 times.
✓ Branch 11 → 12 taken 931474 times.
|
931474 | const auto *header = m_headers->headerAt(mapToSource(index).row()); |
| 48 |
1/2✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 931474 times.
|
931474 | if (!header) return {}; |
| 49 |
24/24✓ Branch 14 → 15 taken 47083 times.
✓ Branch 14 → 21 taken 53527 times.
✓ Branch 14 → 22 taken 40589 times.
✓ Branch 14 → 26 taken 46155 times.
✓ Branch 14 → 27 taken 39630 times.
✓ Branch 14 → 31 taken 30766 times.
✓ Branch 14 → 38 taken 39631 times.
✓ Branch 14 → 44 taken 39844 times.
✓ Branch 14 → 46 taken 39785 times.
✓ Branch 14 → 48 taken 39783 times.
✓ Branch 14 → 50 taken 30674 times.
✓ Branch 14 → 51 taken 39632 times.
✓ Branch 14 → 52 taken 41386 times.
✓ Branch 14 → 62 taken 45840 times.
✓ Branch 14 → 74 taken 39630 times.
✓ Branch 14 → 75 taken 39630 times.
✓ Branch 14 → 76 taken 39630 times.
✓ Branch 14 → 77 taken 39630 times.
✓ Branch 14 → 78 taken 39643 times.
✓ Branch 14 → 84 taken 40018 times.
✓ Branch 14 → 90 taken 39630 times.
✓ Branch 14 → 91 taken 39630 times.
✓ Branch 14 → 101 taken 39630 times.
✓ Branch 14 → 105 taken 78 times.
|
931474 | switch (role) { |
| 50 | 47083 | case Identity: return WorkspaceState::encode({m_accountId, header->folderId, header->uid}); | |
| 51 | 53527 | case Subject: return header->subject; | |
| 52 |
2/2✓ Branch 22 → 23 taken 40589 times.
✓ Branch 23 → 24 taken 40589 times.
|
40589 | case Folder: return m_headers->data(mapToSource(index), MailListModel::FolderBadgeRole); |
| 53 | 46155 | case Sender: return header->from; | |
| 54 |
1/1✓ Branch 27 → 28 taken 39630 times.
|
39630 | case Date: return MailListModel::formatDate(header->date); |
| 55 |
3/3✓ Branch 32 → 33 taken 88 times.
✓ Branch 32 → 34 taken 30678 times.
✓ Branch 33 → 35 taken 88 times.
|
30766 | case Period: return m_period ? m_period(header->date) : QString(); |
| 56 |
2/2✓ Branch 39 → 40 taken 12073 times.
✓ Branch 39 → 42 taken 27558 times.
|
39631 | case MatchedInText: return m_matchedInText ? m_matchedInText(*header) : false; |
| 57 | 39844 | case Unread: return !header->isSeen(); | |
| 58 | 39785 | case Starred: return header->isFlagged(); | |
| 59 | 39783 | case Answered: return header->isAnswered(); | |
| 60 | 30674 | case Labels: return header->labels; | |
| 61 | 39632 | case Attachment: return header->hasAttachments; | |
| 62 | 41386 | case Selected: { | |
| 63 |
5/5✓ Branch 53 → 54 taken 34818 times.
✓ Branch 53 → 57 taken 6568 times.
✓ Branch 54 → 55 taken 34818 times.
✓ Branch 55 → 56 taken 3128 times.
✓ Branch 55 → 57 taken 31690 times.
|
41386 | const bool selected = m_selected && m_selected(header->folderId, header->uid); |
| 64 |
2/2✓ Branch 58 → 59 taken 41386 times.
✓ Branch 59 → 60 taken 41386 times.
|
41386 | m_selectedCache.insert(qMakePair(header->folderId, header->uid), selected); |
| 65 | 41386 | return selected; | |
| 66 | } | ||
| 67 | 45840 | case Suggestion: { | |
| 68 |
4/6✓ Branch 63 → 64 taken 27200 times.
✓ Branch 63 → 66 taken 18640 times.
✓ Branch 67 → 68 taken 27200 times.
✓ Branch 67 → 69 taken 18640 times.
✗ Branch 120 → 121 not taken.
✗ Branch 120 → 122 not taken.
|
73040 | const QString suggestion = m_suggestion ? m_suggestion({m_accountId, header->folderId, header->uid}) : QString{}; |
| 69 |
2/2✓ Branch 69 → 70 taken 45840 times.
✓ Branch 70 → 71 taken 45840 times.
|
45840 | m_suggestionCache.insert(qMakePair(header->folderId, header->uid), suggestion); |
| 70 | 45840 | return suggestion; | |
| 71 | 45840 | } | |
| 72 | // The flat list has no thread structure. Constant neutral roles let one | ||
| 73 | // QML delegate serve both this projection and QuickThreadListModel. | ||
| 74 | 39630 | case Depth: return 0; | |
| 75 | 39630 | case ThreadCount: return 0; | |
| 76 | 39630 | case HasChildren: return false; | |
| 77 | 39630 | case Expanded: return false; | |
| 78 |
2/2✓ Branch 79 → 80 taken 21003 times.
✓ Branch 79 → 82 taken 18640 times.
|
39643 | case OpenTask: return m_taskLink ? m_taskLink(header->messageId) : false; |
| 79 |
2/2✓ Branch 85 → 86 taken 21378 times.
✓ Branch 85 → 88 taken 18640 times.
|
40018 | case RuleMatch: return m_ruleMatch ? m_ruleMatch(*header) : false; |
| 80 | 39630 | case Recipient: return header->to; | |
| 81 |
6/8✓ Branch 91 → 92 taken 1998 times.
✓ Branch 91 → 95 taken 37632 times.
✓ Branch 92 → 93 taken 1998 times.
✓ Branch 94 → 96 taken 1998 times.
✓ Branch 98 → 99 taken 1998 times.
✓ Branch 98 → 100 taken 37632 times.
✗ Branch 133 → 134 not taken.
✗ Branch 133 → 135 not taken.
|
39630 | case SizeText: return header->size > 0 ? QLocale().formattedDataSize(header->size, 0) : QString(); |
| 82 |
1/1✓ Branch 101 → 102 taken 39630 times.
|
39630 | case LabelChips: return labelChipsFor(header->labels); |
| 83 | 78 | default: return MailFilterProxyModel::data(index, role); | |
| 84 | } | ||
| 85 | 74283 | } | |
| 86 | 42643 | QVariantList MailPresentationModel::labelChipsFor(const QStringList &labels) { | |
| 87 | 42643 | QVariantList chips; | |
| 88 |
2/2✓ Branch 30 → 4 taken 2954 times.
✓ Branch 30 → 31 taken 42643 times.
|
45597 | for (const auto &label : labels) { |
| 89 |
3/3✓ Branch 5 → 6 taken 2954 times.
✓ Branch 6 → 7 taken 9 times.
✓ Branch 6 → 8 taken 2945 times.
|
2954 | if (ImapResponseParser::isInternalKeyword(label)) continue; |
| 90 |
1/1✓ Branch 18 → 19 taken 2945 times.
|
2945 | chips.append(QVariantMap{{"name", LabelDelegate::displayName(label)}, |
| 91 |
1/1✓ Branch 11 → 12 taken 2945 times.
|
5890 | {"color", LabelDelegate::colorForLabel(label).name()}, |
| 92 |
3/5✓ Branch 14 → 15 taken 2945 times.
✓ Branch 22 → 23 taken 8835 times.
✓ Branch 22 → 24 taken 2945 times.
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
|
17670 | {"textColor", QColor(Qt::white).name()}}); |
| 93 | } | ||
| 94 | 42643 | return chips; | |
| 95 | 8835 | } | |
| 96 | |||
| 97 | 6526 | QVariantMap MailPresentationModel::mailAt(int row) const { | |
| 98 |
6/7✓ Branch 2 → 3 taken 6526 times.
✗ Branch 2 → 6 not taken.
✓ Branch 4 → 5 taken 6526 times.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 6525 times.
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 10 taken 6525 times.
|
6526 | if (row < 0 || row >= rowCount()) return {}; |
| 99 |
2/2✓ Branch 11 → 12 taken 6525 times.
✓ Branch 12 → 13 taken 6525 times.
|
6525 | return {{"identity", data(index(row, 0), Identity)}, |
| 100 |
2/2✓ Branch 15 → 16 taken 6525 times.
✓ Branch 16 → 17 taken 6525 times.
|
13050 | {"subject", data(index(row, 0), Subject)}, |
| 101 |
4/6✓ Branch 19 → 20 taken 6525 times.
✓ Branch 20 → 21 taken 6525 times.
✓ Branch 24 → 25 taken 19575 times.
✓ Branch 24 → 26 taken 6525 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
|
39150 | {"sender", data(index(row, 0), Sender)}}; |
| 102 | 26100 | } | |
| 103 | 20451 | int MailPresentationModel::rowForIdentity(const QVariantMap &identity) const { | |
| 104 |
1/1✓ Branch 2 → 3 taken 20451 times.
|
20451 | const auto id = WorkspaceState::decode(identity); |
| 105 |
5/6✓ Branch 3 → 4 taken 20451 times.
✗ Branch 3 → 6 not taken.
✓ Branch 5 → 6 taken 2398 times.
✓ Branch 5 → 7 taken 18053 times.
✓ Branch 8 → 9 taken 2398 times.
✓ Branch 8 → 10 taken 18053 times.
|
20451 | if (!m_headers || id.accountId != m_accountId) return -1; |
| 106 |
1/1✓ Branch 10 → 11 taken 18053 times.
|
18053 | const int sourceRow = m_headers->rowForUid(id.uid, id.folderId); |
| 107 |
4/4✓ Branch 11 → 12 taken 16439 times.
✓ Branch 11 → 16 taken 1614 times.
✓ Branch 13 → 14 taken 16439 times.
✓ Branch 14 → 15 taken 16439 times.
|
18053 | return sourceRow < 0 ? -1 : mapFromSource(m_headers->index(sourceRow, 0)).row(); |
| 108 | 20451 | } | |
| 109 | 766 | void MailPresentationModel::filter(const QString &text, bool unreadOnly, bool starredOnly, bool withAttachments) { | |
| 110 | 766 | setFilters(text, unreadOnly, starredOnly, withAttachments); | |
| 111 | 766 | } | |
| 112 | 903 | void MailPresentationModel::clearFilters() { | |
| 113 |
1/1✓ Branch 3 → 4 taken 903 times.
|
903 | setFilters({}, false, false, false); |
| 114 | 903 | } | |
| 115 | 110 | void MailPresentationModel::sortByColumn(const QString &columnId, bool ascending) { | |
| 116 | 110 | int column = -1; | |
| 117 |
1/2✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 110 times.
|
110 | if (columnId == QLatin1String("star")) column = MailListModel::Star; |
| 118 |
1/2✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 110 times.
|
110 | else if (columnId == QLatin1String("subject")) column = MailListModel::Subject; |
| 119 |
1/2✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 110 times.
|
110 | else if (columnId == QLatin1String("from")) column = MailListModel::From; |
| 120 |
1/2✓ Branch 16 → 17 taken 110 times.
✗ Branch 16 → 18 not taken.
|
110 | else if (columnId == QLatin1String("date")) column = MailListModel::Date; |
| 121 | ✗ | else if (columnId == QLatin1String("size")) column = MailListModel::Size; | |
| 122 |
1/2✗ Branch 22 → 23 not taken.
✓ Branch 22 → 24 taken 110 times.
|
110 | if (column < 0) return; |
| 123 |
1/2✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 110 times.
|
110 | sort(column, ascending ? Qt::AscendingOrder : Qt::DescendingOrder); |
| 124 | } | ||
| 125 | 11453 | MailSelectionKey MailPresentationModel::keyAt(int row) const { | |
| 126 |
7/9✓ Branch 2 → 3 taken 11453 times.
✗ Branch 2 → 7 not taken.
✓ Branch 3 → 4 taken 10541 times.
✓ Branch 3 → 7 taken 912 times.
✓ Branch 5 → 6 taken 10541 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 10541 times.
✓ Branch 9 → 10 taken 912 times.
✓ Branch 9 → 12 taken 10541 times.
|
12365 | if (!m_headers || row < 0 || row >= rowCount()) return {}; |
| 127 |
3/3✓ Branch 13 → 14 taken 10541 times.
✓ Branch 14 → 15 taken 10541 times.
✓ Branch 16 → 17 taken 10541 times.
|
10541 | const auto *header = m_headers->headerAt(mapToSource(index(row, 0)).row()); |
| 128 |
1/2✓ Branch 17 → 18 taken 10541 times.
✗ Branch 17 → 19 not taken.
|
10541 | return header ? MailSelectionKey{header->folderId, header->uid, header->date} : MailSelectionKey{}; |
| 129 | 912 | } | |
| 130 | namespace { | ||
| 131 | // P90.12: coalesce rows whose cached role value actually changed into the | ||
| 132 | // minimal set of contiguous ranges. | ||
| 133 | template <typename Value, typename Compute> | ||
| 134 | 4215 | QVector<QPair<int, int>> roleDiffRanges(int rows, | |
| 135 | const std::function<const MailHeader *(int)> &headerAtRow, | ||
| 136 | QHash<QPair<qint64, qint64>, Value> &cache, | ||
| 137 | const Compute &compute) { | ||
| 138 | 4215 | QVector<int> changed; | |
| 139 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 2 → 3 taken 4079 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 2 → 3 taken 136 times.
|
4215 | changed.reserve(8); |
| 140 |
6/6QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 22 → 23 taken 555 times.
✓ Branch 22 → 25 taken 347703 times.
✓ Branch 27 → 4 taken 348258 times.
✓ Branch 27 → 28 taken 4079 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 22 → 4 taken 18051 times.
✓ Branch 22 → 23 taken 136 times.
|
718782 | for (int row = 0; row < rows; ++row) { |
| 141 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 4 → 5 taken 348258 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 4 → 5 taken 18051 times.
|
366309 | const auto *header = headerAtRow(row); |
| 142 |
2/4QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 348258 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 18051 times.
|
731462 | if (!header) continue; |
| 143 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 7 → 8 taken 348258 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 7 → 8 taken 18051 times.
|
366309 | const auto key = qMakePair(header->folderId, header->uid); |
| 144 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 8 → 9 taken 348258 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 8 → 9 taken 18051 times.
|
366309 | const Value value = compute(header); |
| 145 | 366309 | const auto cached = cache.constFind(key); | |
| 146 | // No entry: no view has read this row's value (data() records every | ||
| 147 | // read), so a delegate created later reads the current value itself. | ||
| 148 |
4/4QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 12 → 13 taken 315244 times.
✓ Branch 12 → 14 taken 33014 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 12 → 13 taken 14361 times.
✓ Branch 12 → 14 taken 3690 times.
|
366309 | if (cached == cache.constEnd()) continue; |
| 149 |
4/4QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 16 → 17 taken 32459 times.
✓ Branch 16 → 18 taken 555 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 15 → 16 taken 3089 times.
✓ Branch 15 → 17 taken 601 times.
|
36704 | if (cached.value() == value) continue; |
| 150 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 18 → 19 taken 555 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 17 → 18 taken 601 times.
|
1156 | cache.insert(key, value); |
| 151 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 19 → 20 taken 555 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 18 → 19 taken 601 times.
|
1156 | changed.append(row); |
| 152 | } | ||
| 153 | 4215 | QVector<QPair<int, int>> ranges; | |
| 154 |
4/4QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 45 → 29 taken 118 times.
✓ Branch 45 → 46 taken 4079 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 40 → 24 taken 114 times.
✓ Branch 40 → 41 taken 136 times.
|
4447 | for (int at = 0; at < changed.size();) { |
| 155 | 232 | int end = at; | |
| 156 |
11/12QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 32 → 33 taken 437 times.
✓ Branch 32 → 37 taken 118 times.
✓ Branch 35 → 36 taken 437 times.
✗ Branch 35 → 37 not taken.
✓ Branch 38 → 30 taken 437 times.
✓ Branch 38 → 39 taken 118 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 27 → 28 taken 507 times.
✓ Branch 27 → 32 taken 94 times.
✓ Branch 30 → 31 taken 487 times.
✓ Branch 30 → 32 taken 20 times.
✓ Branch 33 → 25 taken 487 times.
✓ Branch 33 → 34 taken 114 times.
|
1156 | while (end + 1 < changed.size() && changed.at(end + 1) == changed.at(end) + 1) ++end; |
| 157 |
2/2QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<QString, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, QString>&, MailPresentationModel::suggestionsChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 42 → 43 taken 118 times.
QList<std::pair<int, int> > (anonymous namespace)::roleDiffRanges<bool, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1}>(int, std::function<MailHeader const* (int)> const&, QHash<std::pair<long long, long long>, bool>&, MailPresentationModel::selectionChanged()::{lambda(MailHeader const*)#1} const&):
✓ Branch 37 → 38 taken 114 times.
|
232 | ranges.append({changed.at(at), changed.at(end)}); |
| 158 | 232 | at = end + 1; | |
| 159 | } | ||
| 160 | 4215 | return ranges; | |
| 161 | 4215 | } | |
| 162 | } | ||
| 163 | |||
| 164 | 137 | void MailPresentationModel::selectionChanged() { | |
| 165 | // P90.12/P90.17: only rows whose membership flipped re-render (normally | ||
| 166 | // the old and the new selection row), never the entire flat model. | ||
| 167 |
7/9✓ Branch 2 → 3 taken 137 times.
✗ Branch 2 → 8 not taken.
✓ Branch 4 → 5 taken 137 times.
✓ Branch 5 → 6 taken 136 times.
✓ Branch 5 → 8 taken 1 time.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 136 times.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 31 taken 136 times.
|
137 | if (!m_headers || rowCount() <= 0 || !m_selected) { |
| 168 | 1 | const bool had = !m_selectedCache.isEmpty(); | |
| 169 | 1 | m_selectedCache.clear(); | |
| 170 |
4/12✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 18 not taken.
✓ Branch 15 → 16 taken 1 time.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 1 time.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 30 taken 1 time.
✗ Branch 20 → 21 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 27 → 28 not taken.
|
1 | if (had && rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {Selected}); |
| 171 | 1 | return; | |
| 172 | } | ||
| 173 | 136 | for (const auto &range : roleDiffRanges(rowCount(), [this](int row) { | |
| 174 |
3/3✓ Branch 3 → 4 taken 18051 times.
✓ Branch 4 → 5 taken 18051 times.
✓ Branch 6 → 7 taken 18051 times.
|
18051 | return m_headers->headerAt(mapToSource(index(row, 0)).row()); |
| 175 | 136 | }, m_selectedCache, [this](const MailHeader *header) { | |
| 176 | 18051 | return m_selected(header->folderId, header->uid); | |
| 177 |
6/6✓ Branch 33 → 34 taken 136 times.
✓ Branch 34 → 35 taken 136 times.
✓ Branch 36 → 37 taken 136 times.
✓ Branch 37 → 38 taken 136 times.
✓ Branch 49 → 39 taken 114 times.
✓ Branch 49 → 50 taken 136 times.
|
386 | })) |
| 178 |
4/4✓ Branch 40 → 41 taken 114 times.
✓ Branch 42 → 43 taken 114 times.
✓ Branch 44 → 45 taken 114 times.
✓ Branch 45 → 46 taken 114 times.
|
250 | emit dataChanged(index(range.first, 0), index(range.second, 0), {Selected}); |
| 179 | } | ||
| 180 | 2824 | void MailPresentationModel::singleSelectionChanged(MailSelectionKey previous, | |
| 181 | MailSelectionKey current) { | ||
| 182 |
3/7✓ Branch 3 → 4 taken 2824 times.
✗ Branch 3 → 5 not taken.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 2824 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 10 taken 2824 times.
✗ Branch 8 → 9 not taken.
|
2824 | if (!m_selected || !m_headers) { selectionChanged(); return; } |
| 183 | 3880 | const auto update = [this](const MailSelectionKey &key) { | |
| 184 |
3/4✓ Branch 2 → 3 taken 1443 times.
✓ Branch 2 → 4 taken 2437 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1443 times.
|
4093 | if (key.folderId < 0 || key.uid < 0) return; |
| 185 |
1/1✓ Branch 5 → 6 taken 1443 times.
|
1443 | const auto identity = qMakePair(key.folderId, key.uid); |
| 186 |
1/1✓ Branch 6 → 7 taken 1443 times.
|
1443 | const int sourceRow = m_headers->rowForUid(key.uid, key.folderId); |
| 187 |
2/2✓ Branch 7 → 8 taken 92 times.
✓ Branch 7 → 9 taken 1351 times.
|
1443 | const QModelIndex visible = sourceRow < 0 ? QModelIndex{} |
| 188 |
2/2✓ Branch 10 → 11 taken 1351 times.
✓ Branch 11 → 12 taken 1351 times.
|
1443 | : mapFromSource(m_headers->index(sourceRow, 0)); |
| 189 |
3/3✓ Branch 13 → 14 taken 92 times.
✓ Branch 13 → 16 taken 1351 times.
✓ Branch 14 → 15 taken 92 times.
|
1443 | if (!visible.isValid()) { m_selectedCache.remove(identity); return; } |
| 190 |
1/1✓ Branch 16 → 17 taken 1351 times.
|
1351 | const bool selected = m_selected(key.folderId, key.uid); |
| 191 | 1351 | const auto cached = m_selectedCache.constFind(identity); | |
| 192 |
6/6✓ Branch 20 → 21 taken 1333 times.
✓ Branch 20 → 24 taken 18 times.
✓ Branch 22 → 23 taken 121 times.
✓ Branch 22 → 24 taken 1212 times.
✓ Branch 25 → 26 taken 121 times.
✓ Branch 25 → 27 taken 1230 times.
|
1351 | if (cached != m_selectedCache.cend() && cached.value() == selected) return; |
| 193 |
1/1✓ Branch 27 → 28 taken 1230 times.
|
1230 | m_selectedCache.insert(identity, selected); |
| 194 |
2/2✓ Branch 28 → 29 taken 1230 times.
✓ Branch 29 → 30 taken 1230 times.
|
1230 | emit dataChanged(visible, visible, {Selected}); |
| 195 | 2824 | }; | |
| 196 |
1/1✓ Branch 10 → 11 taken 2824 times.
|
2824 | update(previous); |
| 197 |
4/4✓ Branch 11 → 12 taken 2030 times.
✓ Branch 11 → 13 taken 794 times.
✓ Branch 12 → 13 taken 262 times.
✓ Branch 12 → 14 taken 1768 times.
|
2824 | if (previous.folderId != current.folderId || previous.uid != current.uid) |
| 198 |
1/1✓ Branch 13 → 14 taken 1056 times.
|
1056 | update(current); |
| 199 | } | ||
| 200 | 8571 | void MailPresentationModel::suggestionsChanged() { | |
| 201 |
7/9✓ Branch 2 → 3 taken 8571 times.
✗ Branch 2 → 8 not taken.
✓ Branch 4 → 5 taken 8571 times.
✓ Branch 5 → 6 taken 4079 times.
✓ Branch 5 → 8 taken 4492 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 4079 times.
✓ Branch 10 → 11 taken 4492 times.
✓ Branch 10 → 31 taken 4079 times.
|
8571 | if (!m_headers || rowCount() <= 0 || !m_suggestion) { |
| 202 | 4492 | const bool had = !m_suggestionCache.isEmpty(); | |
| 203 | 4492 | m_suggestionCache.clear(); | |
| 204 |
5/12✓ Branch 13 → 14 taken 43 times.
✓ Branch 13 → 18 taken 4449 times.
✓ Branch 15 → 16 taken 43 times.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 43 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 30 taken 4492 times.
✗ Branch 20 → 21 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 27 → 28 not taken.
|
4492 | if (had && rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {Suggestion}); |
| 205 | 4492 | return; | |
| 206 | } | ||
| 207 | 4079 | for (const auto &range : roleDiffRanges(rowCount(), [this](int row) { | |
| 208 |
3/3✓ Branch 3 → 4 taken 348258 times.
✓ Branch 4 → 5 taken 348258 times.
✓ Branch 6 → 7 taken 348258 times.
|
348258 | return m_headers->headerAt(mapToSource(index(row, 0)).row()); |
| 209 | 4079 | }, m_suggestionCache, [this](const MailHeader *header) { | |
| 210 |
1/3✓ Branch 3 → 4 taken 348258 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
|
696516 | return m_suggestion(MailId{m_accountId, header->folderId, header->uid}); |
| 211 |
6/6✓ Branch 33 → 34 taken 4079 times.
✓ Branch 34 → 35 taken 4079 times.
✓ Branch 36 → 37 taken 4079 times.
✓ Branch 37 → 38 taken 4079 times.
✓ Branch 49 → 39 taken 118 times.
✓ Branch 49 → 50 taken 4079 times.
|
8276 | })) |
| 212 |
4/4✓ Branch 40 → 41 taken 118 times.
✓ Branch 42 → 43 taken 118 times.
✓ Branch 44 → 45 taken 118 times.
✓ Branch 45 → 46 taken 118 times.
|
4197 | emit dataChanged(index(range.first, 0), index(range.second, 0), {Suggestion}); |
| 213 | } | ||
| 214 | |||
| 215 | 3 | void MailPresentationModel::setPeriodProvider(std::function<QString(const QDateTime &)> provider) { | |
| 216 | 3 | m_period = std::move(provider); | |
| 217 |
7/8✓ Branch 5 → 6 taken 3 times.
✓ Branch 6 → 7 taken 3 times.
✗ Branch 6 → 17 not taken.
✓ Branch 7 → 8 taken 3 times.
✓ Branch 10 → 11 taken 3 times.
✓ Branch 11 → 12 taken 3 times.
✓ Branch 13 → 14 taken 3 times.
✓ Branch 14 → 15 taken 3 times.
|
3 | if (rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {Period}); |
| 218 | 3 | } | |
| 219 | |||
| 220 | 89 | void MailPresentationModel::setMatchProvider(std::function<bool(const MailHeader &)> provider) { | |
| 221 | 89 | m_matchedInText = std::move(provider); | |
| 222 | 89 | matchesChanged(); | |
| 223 | 89 | } | |
| 224 | |||
| 225 | 89 | void MailPresentationModel::matchesChanged() { | |
| 226 |
2/8✓ Branch 3 → 4 taken 89 times.
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 15 taken 89 times.
✗ Branch 5 → 6 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 11 → 12 not taken.
✗ Branch 12 → 13 not taken.
|
89 | if (rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {MatchedInText}); |
| 227 | 89 | } | |
| 228 | |||
| 229 | 35 | void MailPresentationModel::ruleMatchesChanged() { | |
| 230 |
7/8✓ Branch 3 → 4 taken 35 times.
✓ Branch 4 → 5 taken 35 times.
✗ Branch 4 → 15 not taken.
✓ Branch 5 → 6 taken 35 times.
✓ Branch 8 → 9 taken 35 times.
✓ Branch 9 → 10 taken 35 times.
✓ Branch 11 → 12 taken 35 times.
✓ Branch 12 → 13 taken 35 times.
|
35 | if (rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {RuleMatch}); |
| 231 | 35 | } | |
| 232 | |||
| 233 | 29 | void MailPresentationModel::taskLinksChanged() { | |
| 234 |
8/8✓ Branch 3 → 4 taken 29 times.
✓ Branch 4 → 5 taken 5 times.
✓ Branch 4 → 15 taken 24 times.
✓ Branch 5 → 6 taken 5 times.
✓ Branch 8 → 9 taken 5 times.
✓ Branch 9 → 10 taken 5 times.
✓ Branch 11 → 12 taken 5 times.
✓ Branch 12 → 13 taken 5 times.
|
29 | if (rowCount() > 0) emit dataChanged(index(0, 0), index(rowCount() - 1, 0), {OpenTask}); |
| 235 | 29 | } | |
| 236 |