presentation/MailPresentationModel.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | #include "ui/MailListModel.h" | ||
| 3 | #include "ui/MailFilterProxyModel.h" | ||
| 4 | #include "data/MailSelectionSnapshot.h" | ||
| 5 | #include "data/MailRequest.h" | ||
| 6 | #include <QHash> | ||
| 7 | #include <functional> | ||
| 8 | |||
| 9 | // A role projection over the existing bounded C++ header model, not a JS copy. | ||
| 10 | class MailPresentationModel final : public MailFilterProxyModel { | ||
| 11 | Q_OBJECT | ||
| 12 | public: | ||
| 13 | enum Role { Identity = Qt::UserRole + 100, Subject, Sender, Date, Unread, Starred, Labels, Attachment, Selected, Folder, Suggestion, | ||
| 14 | Depth, ThreadCount, HasChildren, Expanded, LabelChips, OpenTask, RuleMatch, | ||
| 15 | Recipient, SizeText /* F100-30: list columns To and Size */, Period, MatchedInText, | ||
| 16 | Answered /* status column: the IMAP Answered flag */ }; | ||
| 17 | explicit MailPresentationModel(MailListModel *source, QString accountId, QObject *parent = nullptr); | ||
| 18 | QHash<int, QByteArray> roleNames() const override; | ||
| 19 | QVariant data(const QModelIndex &index, int role) const override; | ||
| 20 | Q_INVOKABLE QVariantMap mailAt(int row) const; | ||
| 21 | Q_INVOKABLE int rowForIdentity(const QVariantMap &identity) const; | ||
| 22 | Q_INVOKABLE void filter(const QString &text, bool unreadOnly, bool starredOnly = false, bool withAttachments = false); | ||
| 23 | Q_INVOKABLE void clearFilters(); | ||
| 24 | // Column sorting (flat list only): "star"|"subject"|"from"|"date"|"size". | ||
| 25 | Q_INVOKABLE void sortByColumn(const QString &columnId, bool ascending); | ||
| 26 | Q_PROPERTY(bool sortable READ sortable CONSTANT) | ||
| 27 | 3040 | bool sortable() const { return true; } | |
| 28 | void setAccountId(const QString &accountId); | ||
| 29 | MailSelectionKey keyAt(int row) const; | ||
| 30 | // Presentation chips for the mail list: internal keywords filtered, | ||
| 31 | // LabelDelegate display names/colors reused (translation context kept), | ||
| 32 | // each chip {name, color, textColor}. | ||
| 33 | static QVariantList labelChipsFor(const QStringList &labels); | ||
| 34 | 905 | void setSelectionProvider(std::function<bool(qint64, qint64)> provider) { m_selected = std::move(provider); } | |
| 35 | void selectionChanged(); | ||
| 36 | void singleSelectionChanged(MailSelectionKey previous, MailSelectionKey current); | ||
| 37 | 795 | void setSuggestionProvider(std::function<QString(const MailId &)> provider) { m_suggestion = std::move(provider); } | |
| 38 | void suggestionsChanged(); | ||
| 39 | // S94.5.5: whether a raw Message-ID header has an open linked task. | ||
| 40 | 795 | void setTaskLinkProvider(std::function<bool(const QString &)> provider) { m_taskLink = std::move(provider); } | |
| 41 | // F95-14: whether an enabled server rule matches the row. | ||
| 42 | 795 | void setRuleMatchProvider(std::function<bool(const MailHeader &)> provider) { m_ruleMatch = std::move(provider); } | |
| 43 | void ruleMatchesChanged(); | ||
| 44 | // Sprint 101 S101.5.9: the section label of a row ("March 2025") for a | ||
| 45 | // grouped list; empty without a provider. | ||
| 46 | void setPeriodProvider(std::function<QString(const QDateTime &)> provider); | ||
| 47 | // S101.1.10: whether a search result matched only in its text (the row | ||
| 48 | // shows a glyph); false without a provider. | ||
| 49 | void setMatchProvider(std::function<bool(const MailHeader &)> provider); | ||
| 50 | void matchesChanged(); | ||
| 51 | void taskLinksChanged(); | ||
| 52 | private: | ||
| 53 | MailListModel *m_headers; | ||
| 54 | QString m_accountId; | ||
| 55 | std::function<bool(qint64, qint64)> m_selected; | ||
| 56 | std::function<QString(const MailId &)> m_suggestion; | ||
| 57 | std::function<bool(const QString &)> m_taskLink; | ||
| 58 | std::function<bool(const MailHeader &)> m_ruleMatch; | ||
| 59 | std::function<QString(const QDateTime &)> m_period; | ||
| 60 | std::function<bool(const MailHeader &)> m_matchedInText; | ||
| 61 | // P90.12: last published per-identity role values so selection/suggestion | ||
| 62 | // changes invalidate only rows whose value actually flipped. | ||
| 63 | // Last value each view read through data() (or a published diff). A row | ||
| 64 | // absent here was never read, so a change needs no notification. | ||
| 65 | mutable QHash<QPair<qint64, qint64>, bool> m_selectedCache; | ||
| 66 | mutable QHash<QPair<qint64, qint64>, QString> m_suggestionCache; | ||
| 67 | }; | ||
| 68 |