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

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <QList>
       4              : #include <QSet>
       5              : #include <QStringList>
       6              : #include <QTreeView>
       7              : 
       8              : #include "data/Models.h"
       9              : 
      10              : class QDragEnterEvent;
      11              : class QDragMoveEvent;
      12              : class QDropEvent;
      13              : 
      14              : class QStandardItemModel;
      15              : class QStandardItem;
      16              : 
      17              : // FolderTree displays the IMAP folder hierarchy in the left panel.
      18              : // Renders special folders (INBOX, Sent, Drafts, Trash, Archive) with
      19              : // distinct theme icons and sorts them to the top.
      20              : //
      21              : // Sprint 05: Added section separators, theme icons (no emojis),
      22              : // selectFolder/selectedFolderPath for session restore,
      23              : // expandedFolderPaths/restoreExpandedFolders for state persistence.
      24              : class FolderTree : public QTreeView {
      25           16 :   Q_OBJECT
      26              : 
      27              : public:
      28              :   explicit FolderTree(QWidget *parent = nullptr);
      29              : 
      30              :   // Populate the tree from a flat list of IMAP folders.
      31              :   // Builds a hierarchy based on each folder's delimiter.
      32              :   void setFolders(const QList<FolderInfo> &folders);
      33              : 
      34              :   // Remove all items from the tree
      35              :   void clear();
      36              : 
      37              :   // Programmatically select a folder by its IMAP path.
      38              :   // Used for session state restoration.
      39              :   void selectFolder(const QString &folderPath);
      40              : 
      41              :   // Returns the currently selected folder's IMAP path, or empty string.
      42              :   QString selectedFolderPath() const;
      43              : 
      44              :   // Set the unread count badge for a folder.
      45              :   // count > 0 → shows bold name + count suffix; count == 0 → resets.
      46              :   void setUnreadCount(const QString &folderPath, int count);
      47              : 
      48              :   // T-197: Virtual search folder
      49              :   void showSearchNode(int resultCount);
      50              :   void updateSearchCount(int count);
      51              :   void hideSearchNode();
      52              :   bool isSearchNodeSelected() const;
      53              : 
      54              :   // T-069: Set hidden folders (will be filtered from the tree).
      55           13 :   void setHiddenFolders(const QStringList &hidden) { m_hiddenFolders = hidden; }
      56              : 
      57              :   // Returns list of IMAP paths for all currently expanded items.
      58              :   QStringList expandedFolderPaths() const;
      59              : 
      60              :   // Restores expanded state from a list of IMAP paths.
      61              :   void restoreExpandedFolders(const QStringList &paths);
      62              : 
      63              :   // Returns the model (for testing)
      64           57 :   QStandardItemModel *folderModel() const { return m_model; }
      65              : 
      66              :   // T-289: Check if a folder is a special system folder (INBOX, Sent, etc.)
      67              :   static bool isSpecialFolder(const QString &path, const QStringList &flags);
      68              : 
      69              : signals:
      70              :   // Emitted when the user selects a folder in the tree
      71              :   void folderSelected(const QString &folderPath);
      72              :   // Emitted when the user selects the virtual "Suche" (search results) node,
      73              :   // so the previous search view can be restored.
      74              :   void searchNodeSelected();
      75              :   // Emitted when the user closes the "Suche" node (context menu), so a running
      76              :   // search can be cancelled and the search view dismissed.
      77              :   void searchNodeCloseRequested();
      78              :   // T-069: Emitted when user requests hiding a folder via context menu
      79              :   void folderHideRequested(const QString &folderPath);
      80              :   // T-134: Emitted when user wants to edit folder properties
      81              :   void folderPropertiesRequested(const QString &folderPath);
      82              :   // T-103: Emitted when mails are dropped onto a folder
      83              :   void moveRequested(const QList<qint64> &uids, const QString &targetFolder);
      84              :   void moveMailIdsRequested(const QList<MailIdentity> &mails,
      85              :                             const QString &targetFolder);
      86              :   // T-200: Emitted when user wants to mark all mails as read
      87              :   void markAllReadRequested(const QString &folderPath);
      88              : 
      89              :   // T-289: Folder management signals
      90              :   void createFolderRequested(const QString &parentPath);
      91              :   void deleteFolderRequested(const QString &folderPath);
      92              :   void renameFolderRequested(const QString &folderPath);
      93              :   void moveFolderRequested(const QString &folderPath);
      94              : 
      95              : protected:
      96              :   // T-103: Drop target events
      97              :   void dragEnterEvent(QDragEnterEvent *event) override;
      98              :   void dragMoveEvent(QDragMoveEvent *event) override;
      99              :   void dropEvent(QDropEvent *event) override;
     100              :   void dragLeaveEvent(QDragLeaveEvent *event) override;
     101              :   void paintEvent(QPaintEvent *event) override;
     102              : 
     103              : public:
     104              :   // 67.B2: Re-tint all folder icons with the current theme colors.
     105              :   // Connected to ThemeManager::themeChanged in the constructor.
     106              :   void refreshFolderIcons();
     107              : 
     108              : private:
     109              :   void setupUi();
     110              :   QStandardItem *findOrCreateParent(const QString &path,
     111              :                                     const QString &delimiter);
     112              : 
     113              :   // Returns a QIcon from the system theme for a given folder.
     114              :   static QIcon iconForFolder(const FolderInfo &folder);
     115              : 
     116              :   // 67.B2: Resolve the (possibly custom) icon for one tree item,
     117              :   // tinted with the current theme — shared by setFolders() and
     118              :   // refreshFolderIcons().
     119              :   static QIcon themedItemIcon(const QString &path, const FolderInfo &folder);
     120              : 
     121              :   // T-126: Tint an icon with a solid color (for custom folder colors)
     122              :   static QIcon tintedIcon(const QIcon &icon, const QColor &color);
     123              : 
     124              :   // Find an item by its folder path (recursive).
     125              :   QStandardItem *findItemByPath(const QString &folderPath) const;
     126              :   QStandardItem *findItemByPathRecursive(QStandardItem *root,
     127              :                                          const QString &path) const;
     128              : 
     129              :   // Role to store the IMAP folder path on each item
     130              :   static constexpr int FolderPathRole = Qt::UserRole + 1;
     131              :   // Role to mark separator items
     132              :   static constexpr int SeparatorRole = Qt::UserRole + 2;
     133              :   // Role to store the original display name (e.g. "UCC" not "Arbeit/UCC")
     134              :   static constexpr int DisplayNameRole = Qt::UserRole + 3;
     135              :   // Role to store the hierarchy delimiter (e.g. "/" or ".")
     136              :   static constexpr int DelimiterRole = Qt::UserRole + 4;
     137              :   // T-289: Role to store IMAP flags (e.g. "\Sent", "\Trash") as QStringList
     138              :   static constexpr int FolderFlagsRole = Qt::UserRole + 5;
     139              : 
     140              : public:
     141              :   // 67.B4: Role storing the unread count (painted as a badge pill by
     142              :   // FolderBadgeDelegate; the item text stays the plain folder name)
     143              :   static constexpr int UnreadCountRole = Qt::UserRole + 6;
     144              : 
     145              : private:
     146              : 
     147              :   QStandardItemModel *m_model = nullptr;
     148              :   QStringList m_hiddenFolders; // T-069
     149              :   QSet<QString> m_hiddenSet;   // T-078: computed from m_hiddenFolders
     150              : 
     151              :   // T-525: O(1) path→item cache (replaces recursive tree search)
     152              :   QHash<QString, QStandardItem *> m_pathCache;
     153              : 
     154              :   // DnD visual highlight (avoids triggering folderSelected during drag)
     155              :   QPersistentModelIndex m_dragHighlightIndex;
     156              :   QPersistentModelIndex m_preDragIndex;
     157              : 
     158              :   // T-197: Virtual search node
     159              :   QStandardItem *m_searchItem = nullptr;
     160              :   static constexpr auto SearchNodePath = "__SEARCH__";
     161              : };
        

Generated by: LCOV version 2.0-1