MailJD nbsp;·nbsp; Test Dashboard nbsp;·nbsp; Coverage
LCOV - code coverage report
Current view: top level - ui - MailListModel.h (source / functions) Coverage Total Hit
Test: MailJD Coverage (Unit + E2E) Lines: 100.0 % 2 2
Test Date: 2026-06-21 21:10:19 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <QAbstractTableModel>
       4              : #include <QHash>
       5              : #include <QList>
       6              : #include <QMimeData>
       7              : #include <QPair>
       8              : 
       9              : #include "data/Models.h"
      10              : 
      11              : // MailListModel displays mail headers in a table format (Star, Subject, From,
      12              : // Date, Size). Designed for use with QSortFilterProxyModel for sorting. Unread
      13              : // (unseen) mails are rendered in bold (FontRole). Star column shows ⭐ for
      14              : // flagged mails.
      15              : class MailListModel : public QAbstractTableModel {
      16         5310 :   Q_OBJECT
      17              : 
      18              : public:
      19              :   // T-514: Composite identity key (folderId, uid) — UIDs are only unique per folder
      20              :   using MailKey = QPair<qint64, qint64>;
      21              :   // Column order: Star/status column first (narrow icon), then attachment
      22              :   // indicator, then content.
      23              :   enum Column { Star = 0, Attachment, Subject, Suggestion, From, Date, Size, ColumnCount };
      24              : 
      25              :   // Custom roles for filtering/sorting beyond Qt::UserRole
      26              :   enum Role {
      27              :     SortRole = Qt::UserRole,       // Raw values for proper sorting
      28              :     FlagsRole = Qt::UserRole + 1,  // quint32 flags bitmask
      29              :     HasAttachmentsRole = Qt::UserRole + 2, // bool: has attachments
      30              :     LabelsRole = Qt::UserRole + 3, // QStringList: IMAP keywords/labels
      31              :     SuggestionConfRole = Qt::UserRole + 10, // double: suggestion confidence
      32              :   };
      33              : 
      34              :   explicit MailListModel(QObject *parent = nullptr);
      35              : 
      36              :   // QAbstractTableModel interface
      37              :   int rowCount(const QModelIndex &parent = {}) const override;
      38              :   int columnCount(const QModelIndex &parent = {}) const override;
      39              :   QVariant data(const QModelIndex &index,
      40              :                 int role = Qt::DisplayRole) const override;
      41              :   QVariant headerData(int section, Qt::Orientation orientation,
      42              :                       int role = Qt::DisplayRole) const override;
      43              : 
      44              :   // Sprint 76 (T-76.B3): re-emit header data so translated column headers
      45              :   // (Subject/From/Date/Size/Has attachment) refresh on a live language switch.
      46              :   void retranslateUi();
      47              : 
      48              :   // T-102: Drag & Drop support
      49              :   Qt::ItemFlags flags(const QModelIndex &index) const override;
      50              :   QStringList mimeTypes() const override;
      51              :   QMimeData *mimeData(const QModelIndexList &indexes) const override;
      52              :   Qt::DropActions supportedDragActions() const override;
      53              : 
      54              :   // --- Data management ---
      55              : 
      56              :   // Replace all headers (initial load from cache).
      57              :   void setHeaders(const QList<MailHeader> &headers);
      58              : 
      59              :   // Append new headers (incremental sync from IMAP).
      60              :   void appendHeaders(const QList<MailHeader> &headers);
      61              : 
      62              :   // Clear all data.
      63              :   void clear();
      64              : 
      65              :   // Update flags for a specific UID. Emits dataChanged for the row.
      66              :   // T-514: folderId required for composite key lookup.
      67              :   void updateFlags(qint64 uid, quint32 newFlags, qint64 folderId);
      68              : 
      69              :   // T-71: Update attachment status for a row (called after storeAttachments).
      70              :   void setHasAttachments(qint64 uid, qint64 folderId, bool has);
      71              : 
      72              :   // Remove a mail by UID. Uses beginRemoveRows/endRemoveRows.
      73              :   // T-514: folderId required for composite key lookup.
      74              :   void removeByUid(qint64 uid, qint64 folderId);
      75              : 
      76              :   // T-525/Cx8: Batch remove — single rebuild instead of O(N²)
      77              :   // T-514: folderId required (all UIDs must be from the same folder).
      78              :   void removeByUids(const QList<qint64> &uids, qint64 folderId);
      79              : 
      80              :   // Get the header at a given row. Returns nullptr if out of range.
      81              :   const MailHeader *headerAt(int row) const;
      82              :   MailHeader *mutableHeaderAt(int row);
      83              : 
      84              :   // Get the UID at a given row. Returns -1 if out of range.
      85              :   qint64 uidAt(int row) const;
      86              : 
      87              :   // Find the row index for a given UID. Returns -1 if not found.
      88              :   // T-514: folderId required for composite key lookup.
      89              :   int rowForUid(qint64 uid, qint64 folderId) const;
      90              : 
      91              :   // Count of unseen (unread) mails in the current model.
      92              :   int unreadCount() const;
      93              : 
      94              :   // T-099: Access the full header list for thread model population.
      95           64 :   const QList<MailHeader> &allHeaders() const { return m_headers; }
      96              : 
      97              :   // T-232: Set/clear folder suggestion for a specific UID.
      98              :   // T-514: folderId required for composite key lookup.
      99              :   void setSuggestion(qint64 uid, qint64 folderId, const QString &text, double confidence);
     100              :   void clearSuggestions();
     101              : 
     102              : public:
     103              :   // 67.B4: humanized date for the Date column (shared with
     104              :   // MailThreadModel). Today "14:32" · yesterday "Yesterday" · this week
     105              :   // "Mon" · this year "12. May" · older "12.05.2024".
     106              :   static QString formatDate(const QDateTime &dt);
     107              : 
     108              : private:
     109              : 
     110              :   // Format size for display: "1.2 KB", "3.4 MB"
     111              :   static QString formatSize(qint64 bytes);
     112              : 
     113              :   // T-115: Rebuild the UID→row index from m_headers.
     114              :   void rebuildUidIndex();
     115              : 
     116              :   QList<MailHeader> m_headers;
     117              : 
     118              :   // T-514: O(1) (folderId,UID)→row lookup index.
     119              :   // Maintained in sync with m_headers by all mutating methods.
     120              :   QHash<MailKey, int> m_uidIndex;
     121              : 
     122              :   // T-116: Cached unread (unseen) count — avoids O(n) scan on each query.
     123              :   // Maintained by all mutating methods (setHeaders, appendHeaders,
     124              :   // updateFlags, removeByUid, clear).
     125              :   int m_unreadCount = 0;
     126              : 
     127              :   // T-232: Suggestion cache — (folderId,UID) → display text + confidence
     128              :   struct SuggestionData {
     129              :     QString text;       // e.g. "→ Projekte 96%"
     130              :     double confidence;  // for color coding
     131              :   };
     132              :   QHash<MailKey, SuggestionData> m_suggestionCache;
     133              : };
        

Generated by: LCOV version 2.0-1