Branch data Line data Source code
1 : : #pragma once
2 : :
3 : : #include <QDialog>
4 : : #include <QTemporaryDir>
5 : : #include <QTimer>
6 : : #include <memory>
7 : :
8 : : class QAction;
9 : : class QDragEnterEvent;
10 : : class QDragLeaveEvent;
11 : : class QDropEvent;
12 : : class QLabel;
13 : : class QLineEdit;
14 : : class QToolBar;
15 : : class QWidget;
16 : :
17 : : struct SmtpConfig;
18 : : class SmtpService;
19 : : class ContactStore;
20 : : class ContactCompleter;
21 : : class MentionTextEdit;
22 : :
23 : : // ComposeWindow is the email composition dialog.
24 : : // T-105: Redesigned with toolbar, BCC field, monospace body, discard dialog.
25 : : class ComposeWindow : public QDialog {
26 : 1206 : Q_OBJECT
27 : :
28 : : public:
29 : : explicit ComposeWindow(QWidget *parent = nullptr);
30 : :
31 : : // Pre-fill fields (for Reply/Forward)
32 : : void setTo(const QString &to);
33 : : void setCc(const QString &cc);
34 : : void setBcc(const QString &bcc); // T-177: needed for Draft loading
35 : : void setSubject(const QString &subject);
36 : : void setBody(const QString &body);
37 : : void setFrom(const QString &from);
38 : :
39 : : // T-79.E5: read-only accessors (regression tests, status displays)
40 : : QString subject() const;
41 : : QString body() const;
42 : :
43 : : // T-177: Draft tracking
44 : 7 : void setDraftUid(qint64 uid) { m_draftUid = uid; }
45 : 23 : qint64 draftUid() const { return m_draftUid; }
46 : : // T-624/FUNC-14: Start auto-save timer when drafts folder becomes available
47 : 33 : void setDraftsFolder(const QString &folder) {
48 : 33 : m_draftsFolder = folder;
49 [ + - + + : 33 : if (m_autoSaveTimer && !folder.isEmpty())
+ + ]
50 : 10 : m_autoSaveTimer->start();
51 : 33 : }
52 : : bool hasUnsavedChanges() const;
53 : : void saveDraft();
54 : : void markDraftSaved();
55 : : void markDraftSaveFailed(const QString &error);
56 : :
57 : : // Set the SMTP configuration for sending
58 : : void setSmtpConfig(const SmtpConfig &config);
59 : :
60 : : // T-156: Set contact store for autocomplete in address fields
61 : : void setContactStore(ContactStore *store);
62 : :
63 : : // Add an attachment that already exists in the local cache, for example
64 : : // when reopening drafts or forwarding cached messages.
65 : : bool addAttachmentData(const QString &filename, const QByteArray &data,
66 : : const QByteArray &mimeType = {});
67 : :
68 : : // T-184: Build the RFC-2822 message (reusable for Draft/Sent)
69 : : QByteArray buildMessage(bool includeBcc = true,
70 : : QString *errorMessage = nullptr);
71 : :
72 : : // T-184: Access last built message (for Sent-copy after SMTP send)
73 : 8 : QByteArray lastBuiltMessage() const { return m_lastBuiltMessage; }
74 : 4 : QString lastMessageId() const { return m_lastMessageId; }
75 : :
76 : : // T-184: Threading fields (set before opening for Reply/Forward)
77 : 9 : void setInReplyTo(const QString &messageId) { m_inReplyTo = messageId; }
78 : 9 : void setReferences(const QStringList &refs) { m_references = refs; }
79 : :
80 : : signals:
81 : : void messageSent();
82 : : // T-155: Emitted after successful send with parsed recipients
83 : : void recipientsSent(const QStringList &toList, const QStringList &ccList,
84 : : const QStringList &bccList);
85 : : // T-177: Draft signals
86 : : void draftSaveRequested(const QByteArray &rfcMessage);
87 : : void draftDiscarded(qint64 draftUid);
88 : :
89 : : protected:
90 : : // T-105: Discard confirmation on close
91 : : void closeEvent(QCloseEvent *event) override;
92 : : // T-107: Drag & drop file attachments
93 : : void dragEnterEvent(QDragEnterEvent *event) override;
94 : : void dragLeaveEvent(QDragLeaveEvent *event) override;
95 : : void dropEvent(QDropEvent *event) override;
96 : :
97 : : private slots:
98 : : void onSendClicked();
99 : : void onAttachClicked();
100 : : void onDiscardClicked();
101 : :
102 : : private:
103 : : // T-304: Runtime language switching
104 : : void retranslateUi();
105 : :
106 : : protected:
107 : : void changeEvent(QEvent *event) override;
108 : :
109 : : void setupUi();
110 : : QString currentContentSnapshot() const; // T-177: dirty-check helper
111 : : QStringList parseRecipients(const QString &field) const;
112 : : QStringList parseRecipientList(const QString &field) const;
113 : : // T-106: Attachment chip management
114 : : void addAttachment(const QString &path);
115 : : void removeAttachment(int index);
116 : : void refreshAttachmentBar();
117 : : void showDropOverlay(bool show);
118 : :
119 : : // Toolbar
120 : : QToolBar *m_toolbar = nullptr;
121 : : QAction *m_discardAction = nullptr;
122 : : QAction *m_attachAction = nullptr;
123 : : QAction *m_sendAction = nullptr;
124 : :
125 : : // Header fields
126 : : QLineEdit *m_fromEdit = nullptr;
127 : : QLineEdit *m_toEdit = nullptr;
128 : : QLineEdit *m_ccEdit = nullptr;
129 : : QLineEdit *m_bccEdit = nullptr; // T-105: hidden by default
130 : : QLabel *m_ccBccLabel = nullptr; // T-105: toggle link
131 : : QLineEdit *m_subjectEdit = nullptr;
132 : :
133 : : // Body + status
134 : : MentionTextEdit *m_bodyEdit = nullptr;
135 : : QLabel *m_statusLabel = nullptr;
136 : :
137 : : // SMTP
138 : : SmtpService *m_smtp = nullptr;
139 : : std::unique_ptr<SmtpConfig> m_smtpConfig; // T-507: was raw pointer (leak)
140 : : QStringList m_attachmentPaths;
141 : : std::unique_ptr<QTemporaryDir> m_restoredAttachmentDir;
142 : :
143 : : // T-106: Attachment chip bar
144 : : QWidget *m_attachmentBar = nullptr;
145 : : QLabel *m_attachmentSizeLabel = nullptr;
146 : :
147 : : // T-107: Drop overlay
148 : : QWidget *m_dropOverlay = nullptr;
149 : :
150 : : // T-156: Contact autocomplete
151 : : ContactStore *m_contactStore = nullptr;
152 : : ContactCompleter *m_toCompleter = nullptr;
153 : : ContactCompleter *m_ccCompleter = nullptr;
154 : : ContactCompleter *m_bccCompleter = nullptr;
155 : :
156 : : // T-184: Threading and message state
157 : : QString m_inReplyTo;
158 : : QStringList m_references;
159 : : QByteArray m_lastBuiltMessage;
160 : : QString m_lastMessageId;
161 : :
162 : : // T-177: Draft state
163 : : qint64 m_draftUid = -1; // UID of the saved draft (-1 = none)
164 : : QString m_draftsFolder; // IMAP Drafts folder path
165 : : QTimer *m_autoSaveTimer = nullptr; // Auto-save every 60s
166 : : QString m_lastSavedContent; // Snapshot after last save (dirty-check)
167 : : bool m_closeAfterDraftSave = false;
168 : : bool m_wasSentSuccessfully = false; // Prevents draft-save prompt after send
169 : : };
|