Line data Source code
1 : #pragma once
2 :
3 : #include <QMap>
4 : #include <QSet>
5 : #include <QWidget>
6 :
7 : #include "data/Models.h"
8 :
9 : class QTreeView;
10 : class FolderPredictor;
11 :
12 : struct SuggestionInfo {
13 : QString folderShort; // Short display name (last path segment)
14 : QString folderFull; // Full IMAP path
15 : double confidence = 0.0; // 0.0–1.0
16 : bool isSpam = false; // X-Spam header detected
17 : bool isAlternate = false; // T-234: Currently showing 2nd suggestion
18 : };
19 :
20 : // T-232: Overlay widget that paints folder suggestion badges over the mail list.
21 : // Activated/deactivated via Ctrl+S. Paints transparent badges next to each
22 : // visible row showing the predicted folder and confidence level (color-coded).
23 : // Predictions are computed lazily — only for visible rows during paintEvent.
24 : class SuggestionOverlay : public QWidget {
25 : Q_OBJECT
26 : #ifdef MAILJD_UNIT_TEST
27 : friend class TestSuggestionOverlay;
28 : #endif
29 :
30 : public:
31 : SuggestionOverlay(QTreeView *mailList, QWidget *parent = nullptr);
32 :
33 : // Activate the overlay (fast — just stores references, no prediction).
34 : void activate(FolderPredictor *predictor,
35 : const QList<MailHeader> &headers,
36 : const QString ¤tFolder,
37 : const QString &junkFolder);
38 :
39 : // Hide the overlay.
40 : void deactivate();
41 :
42 : // Is the overlay currently active?
43 10 : bool isActive() const { return m_active; }
44 :
45 : // T-234: Toggle between 1st and 2nd suggestion for a specific UID.
46 : void toggleAlternate(qint64 uid);
47 :
48 : // Get the current suggestion for a UID (respects alternate toggle).
49 : SuggestionInfo suggestionForUid(qint64 uid) const;
50 :
51 : protected:
52 : void paintEvent(QPaintEvent *event) override;
53 : bool eventFilter(QObject *obj, QEvent *event) override;
54 :
55 : private:
56 : QTreeView *m_mailList;
57 : bool m_active = false;
58 :
59 : // Stored references for lazy prediction
60 : FolderPredictor *m_predictor = nullptr;
61 : QString m_currentFolder;
62 : QString m_junkFolder;
63 :
64 : // UID → MailHeader for lazy lookup
65 : QMap<qint64, MailHeader> m_headersByUid;
66 : // Row index → UID mapping (source model order)
67 : QList<qint64> m_rowUids;
68 :
69 : // UID → primary SuggestionInfo (lazily populated)
70 : QMap<qint64, SuggestionInfo> m_suggestions;
71 : // UID → secondary SuggestionInfo (lazily populated)
72 : QMap<qint64, SuggestionInfo> m_altSuggestions;
73 : // UIDs that have been predicted (avoid re-computation)
74 : QSet<qint64> m_predicted;
75 : // UIDs currently showing the alternate suggestion
76 : QSet<qint64> m_showingAlternate;
77 :
78 : // Compute prediction for a single UID (if not already cached)
79 : void ensurePrediction(qint64 uid);
80 :
81 : // Color scale for confidence levels
82 : QColor confidenceColor(double confidence) const;
83 :
84 : // Extract short folder name from full IMAP path
85 : static QString shortFolderName(const QString &fullPath);
86 : };
|