File indexing completed on 2024-11-24 04:53:00
0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 0002 0003 This file is part of the Trojita Qt IMAP e-mail client, 0004 http://trojita.flaska.net/ 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License as 0008 published by the Free Software Foundation; either version 2 of 0009 the License or (at your option) version 3 or any later version 0010 accepted by the membership of KDE e.V. (or its successor approved 0011 by the membership of KDE e.V.), which shall act as a proxy 0012 defined in Section 14 of version 3 of the license. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 #ifndef COMPOSEWIDGET_H 0023 #define COMPOSEWIDGET_H 0024 0025 #include <memory> 0026 0027 #include <QList> 0028 #include <QMap> 0029 #include <QPersistentModelIndex> 0030 #include <QUrl> 0031 #include <QPointer> 0032 #include <QWidget> 0033 0034 #include "Common/Logging.h" 0035 #include "Composer/Recipients.h" 0036 #include "Composer/MessageComposer.h" 0037 #include "Plugins/AddressbookPlugin.h" 0038 0039 0040 namespace Ui 0041 { 0042 class ComposeWidget; 0043 } 0044 0045 class QAbstractListModel; 0046 class QActionGroup; 0047 class QComboBox; 0048 class QLineEdit; 0049 class QMenu; 0050 class QPushButton; 0051 class QSettings; 0052 class QToolButton; 0053 0054 namespace Composer { 0055 class Submission; 0056 } 0057 0058 namespace MSA { 0059 class MSAFactory; 0060 } 0061 0062 namespace Gui 0063 { 0064 0065 class MainWindow; 0066 0067 class InhibitComposerDirtying; 0068 0069 class ComposerSaveState; 0070 0071 /** @short A "Compose New Mail..." dialog 0072 0073 Implements a widget which can act as a standalone window for composing e-mail messages. 0074 Uses Imap::Mailbox::MessageComposer as a backend for composing a message. @see Imap::Mailbox::MessageComposer 0075 0076 */ 0077 class ComposeWidget : public QWidget 0078 { 0079 Q_OBJECT 0080 public: 0081 ~ComposeWidget(); 0082 static ComposeWidget *warnIfMsaNotConfigured(ComposeWidget *widget, MainWindow *mainWindow); 0083 static ComposeWidget *createDraft(MainWindow *mainWindow, const QString &path); 0084 static ComposeWidget *createBlank(MainWindow *mainWindow); 0085 static ComposeWidget *createFromUrl(MainWindow *mainWindow, const QUrl &url); 0086 static ComposeWidget *createReply(MainWindow *mainWindow, const Composer::ReplyMode &mode, const QModelIndex &replyingToMessage, 0087 const QList<QPair<Composer::RecipientKind, QString> > &recipients, const QString &subject, 0088 const QString &body, const QList<QByteArray> &inReplyTo, const QList<QByteArray> &references); 0089 static ComposeWidget *createForward(MainWindow *mainWindow, const Composer::ForwardMode mode, const QModelIndex &forwardingMessage, 0090 const QString &subject, const QList<QByteArray> &inReplyTo, const QList<QByteArray> &references); 0091 static ComposeWidget *createFromReadOnly(MainWindow *mainWindow, const QModelIndex &messageRoot, const QList<QPair<Composer::RecipientKind, QString>> &recipients); 0092 void placeOnMainWindow(); 0093 protected: 0094 void changeEvent(QEvent *e); 0095 void closeEvent(QCloseEvent *ce); 0096 bool eventFilter(QObject *o, QEvent *e); 0097 0098 private slots: 0099 void calculateMaxVisibleRecipients(); 0100 void collapseRecipients(); 0101 void completeRecipient(QAction *act); 0102 void completeRecipients(const QString &text); 0103 void send(); 0104 void gotError(const QString &error); 0105 void sent(); 0106 void updateRecipientList(); 0107 void scrollRecipients(int); 0108 void gotoNextInputLineFrom(QWidget *w); 0109 void handleFocusChange(); 0110 void scrollToFocus(); 0111 void slotFadeFinished(); 0112 0113 void slotCheckAddressOfSender(); 0114 void slotCheckAddress(QLineEdit *edit); 0115 0116 void slotAskForFileAttachment(); 0117 void slotAttachFiles(QList<QUrl> urls); 0118 0119 void slotUpdateSignature(); 0120 void updateWindowTitle(); 0121 0122 void autoSaveDraft(); 0123 void setMessageUpdated(); 0124 0125 void setUiWidgetsEnabled(const bool enabled); 0126 0127 void onCompletionAvailable(const Plugins::NameEmailList &completion); 0128 void onCompletionFailed(Plugins::AddressbookJob::Error error); 0129 0130 void passwordRequested(const QString &user, const QString &host); 0131 void passwordError(); 0132 void toggleReplyMarking(); 0133 void updateReplyMarkingAction(); 0134 void updateReplyMode(); 0135 void markReplyModeHandpicked(); 0136 0137 signals: 0138 void logged(const Common::LogKind kind, const QString& source, const QString& message); 0139 0140 private: 0141 ComposeWidget(MainWindow *mainWindow, std::shared_ptr<Composer::AbstractComposer> messageComposer, MSA::MSAFactory *msaFactory); 0142 void setResponseData(const QList<QPair<Composer::RecipientKind, QString> > &recipients, const QString &subject, 0143 const QString &body, const QList<QByteArray> &inReplyTo, const QList<QByteArray> &references, 0144 const QModelIndex &replyingToMessage); 0145 bool setReplyMode(const Composer::ReplyMode mode); 0146 0147 static QByteArray extractMailAddress(const QString &text, bool &ok); 0148 static Composer::RecipientKind recipientKindForNextRow(const Composer::RecipientKind kind); 0149 void addRecipient(int position, Composer::RecipientKind kind, const QString &address); 0150 bool parseRecipients(QList<QPair<Composer::RecipientKind, Imap::Message::MailAddress> > &results, QString &errorMessage); 0151 void removeRecipient(int position); 0152 void fadeIn(QWidget *w); 0153 void askPassword(const QString &user, const QString &host); 0154 0155 bool buildMessageData(); 0156 bool shouldBuildMessageLocally() const; 0157 0158 void saveDraft(const QString &path); 0159 void loadDraft(const QString &path); 0160 0161 std::shared_ptr<Composer::MessageComposer> interactiveComposer(); 0162 0163 Ui::ComposeWidget *ui; 0164 QPushButton *sendButton; 0165 QPushButton *cancelButton; 0166 QToolButton *m_markButton; 0167 QActionGroup *m_markAsReply; 0168 QAction *m_actionStandalone; 0169 QAction *m_actionInReplyTo; 0170 QAction *m_actionToggleMarking; 0171 QToolButton *m_replyModeButton; 0172 QActionGroup *m_replyModeActions; 0173 QAction *m_actionHandPickedRecipients; 0174 QAction *m_actionReplyModePrivate; 0175 QAction *m_actionReplyModeAllButMe; 0176 QAction *m_actionReplyModeAll; 0177 QAction *m_actionReplyModeList; 0178 typedef QPair<QComboBox*, QLineEdit*> Recipient; 0179 QList<Recipient> m_recipients; 0180 QTimer *m_recipientListUpdateTimer; 0181 QPointer<QWidget> m_lastFocusedRecipient; 0182 int m_maxVisibleRecipients; 0183 0184 bool m_sentMail; 0185 bool m_explicitDraft; 0186 QString m_autoSavePath; 0187 0188 QList<QByteArray> m_inReplyTo; 0189 QList<QByteArray> m_references; 0190 QPersistentModelIndex m_replyingToMessage; 0191 0192 std::unique_ptr<ComposerSaveState> m_saveState; 0193 0194 bool m_appendUidReceived; 0195 uint m_appendUidValidity; 0196 uint m_appendUid; 0197 bool m_genUrlAuthReceived; 0198 QString m_urlauth; 0199 0200 MainWindow *m_mainWindow; 0201 QSettings *m_settings; 0202 0203 std::shared_ptr<Composer::AbstractComposer> m_composer; 0204 Composer::Submission *m_submission; 0205 0206 QMenu *m_completionPopup; 0207 QLineEdit *m_completionReceiver; 0208 int m_completionCount; 0209 0210 QMap<QLineEdit *, Plugins::AddressbookJob *> m_firstCompletionRequests; 0211 QMap<QLineEdit *, Plugins::AddressbookJob *> m_secondCompletionRequests; 0212 0213 friend class InhibitComposerDirtying; 0214 friend class ComposerSaveState; 0215 0216 ComposeWidget(const ComposeWidget &); // don't implement 0217 ComposeWidget &operator=(const ComposeWidget &); // don't implement 0218 }; 0219 0220 } 0221 0222 #endif // COMPOSEWIDGET_H