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