ui/MailFilterProxyModel.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QSet> | ||
| 4 | #include <QSortFilterProxyModel> | ||
| 5 | |||
| 6 | // MailFilterProxyModel filters the mail list based on programmatic state. | ||
| 7 | // Supports: unread-only, starred-only, text search (subject/from). | ||
| 8 | // Sits between MailListModel and the QTreeView. | ||
| 9 | // | ||
| 10 | // Sprint 15: QuickFilterBar dependency removed. Filters are now set directly | ||
| 11 | // via setFilterText(), setShowUnreadOnly(), etc. from CommandBar commands. | ||
| 12 | class MailFilterProxyModel : public QSortFilterProxyModel { | ||
| 13 | Q_OBJECT | ||
| 14 | |||
| 15 | public: | ||
| 16 | explicit MailFilterProxyModel(QObject *parent = nullptr); | ||
| 17 | |||
| 18 | // T-146: Direct filter setters (replace QuickFilterBar) | ||
| 19 | void setFilterText(const QString &text); | ||
| 20 | void setShowUnreadOnly(bool on); | ||
| 21 | void setShowStarredOnly(bool on); | ||
| 22 | void setShowWithAttachments(bool on); | ||
| 23 | // Publish a multi-field filter intent with one proxy invalidation. | ||
| 24 | void setFilters(const QString &text, bool unreadOnly, bool starredOnly, | ||
| 25 | bool withAttachments); | ||
| 26 | |||
| 27 | 1401 | bool showUnreadOnly() const { return m_showUnread; } | |
| 28 | 1405 | bool showStarredOnly() const { return m_showStarred; } | |
| 29 | 1413 | bool showWithAttachments() const { return m_showAttachments; } | |
| 30 | 1389 | QString filterText() const { return m_filterText; } | |
| 31 | // Mails the unread view showed in `folderId` (they stay listed once read). | ||
| 32 | 9 | QSet<qint64> shownUnread(qint64 folderId) const { | |
| 33 |
2/2✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 4 taken 7 times.
|
9 | return folderId == m_shownUnreadFolder ? m_shownUnread : QSet<qint64>{}; |
| 34 | } | ||
| 35 | // P90 gate "one model commit per filter intent": when the source replaces | ||
| 36 | // its rows with a page already filtered by the new criteria, the driver | ||
| 37 | // returns true after starting that reload; the proxy then only adopts the | ||
| 38 | // criteria and the source's reset re-filters in the same commit. Without a | ||
| 39 | // driver (or when it returns false) the proxy filters the loaded rows now. | ||
| 40 | 795 | void setSourceFilterDriver(std::function<bool()> driver) { m_sourceFilterDriver = std::move(driver); } | |
| 41 | |||
| 42 | signals: | ||
| 43 | // Selection is owned by MailId in MainWindow. These bracket filter changes | ||
| 44 | // because QSortFilterProxyModel otherwise invalidates QModelIndexes without | ||
| 45 | // exposing the semantic transition to the view owner. | ||
| 46 | void mailFilterAboutToChange(); | ||
| 47 | void mailFilterChanged(); | ||
| 48 | |||
| 49 | protected: | ||
| 50 | bool lessThan(const QModelIndex &sourceLeft, | ||
| 51 | const QModelIndex &sourceRight) const override; | ||
| 52 | bool filterAcceptsRow(int sourceRow, | ||
| 53 | const QModelIndex &sourceParent) const override; | ||
| 54 | |||
| 55 | private: | ||
| 56 | void invalidateMailFilter(); | ||
| 57 | 1053 | void forgetShownUnread() { m_shownUnread.clear(); m_shownUnreadFolder = -1; } | |
| 58 | |||
| 59 | // Mails shown while the unread filter is active stay listed after they are | ||
| 60 | // read (opening a mail marks it read) until the filter or folder changes. | ||
| 61 | mutable QSet<qint64> m_shownUnread; | ||
| 62 | mutable qint64 m_shownUnreadFolder = -1; | ||
| 63 | QString m_filterText; | ||
| 64 | bool m_showUnread = false; | ||
| 65 | bool m_showStarred = false; | ||
| 66 | bool m_showAttachments = false; | ||
| 67 | std::function<bool()> m_sourceFilterDriver; | ||
| 68 | }; | ||
| 69 |