kmcomposerwin.cpp 154 KB
Newer Older
Volker Krause's avatar
Volker Krause committed
1 2
/*
 * This file is part of KMail.
Laurent Montel's avatar
Laurent Montel committed
3
 * Copyright (c) 2011-2019 Laurent Montel <montel@kde.org>
4
 *
Volker Krause's avatar
Volker Krause committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
 *
 * Based on KMail code by:
 * Copyright (c) 1997 Markus Wuebben <markus.wuebben@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
Laurent Montel's avatar
Laurent Montel committed
24
#include "kmcomposerwin.h"
Volker Krause's avatar
Volker Krause committed
25
// KMail includes
Laurent Montel's avatar
Laurent Montel committed
26 27
#include "attachment/attachmentcontroller.h"
#include "attachment/attachmentview.h"
28
#include "codec/codecaction.h"
Sandro Knauß's avatar
Sandro Knauß committed
29
#include "custommimeheader.h"
30
#include "editor/kmcomposereditorng.h"
Sandro Knauß's avatar
Sandro Knauß committed
31 32 33
#include "editor/plugininterface/kmailplugineditorcheckbeforesendmanagerinterface.h"
#include "editor/plugininterface/kmailplugineditorinitmanagerinterface.h"
#include "editor/plugininterface/kmailplugineditormanagerinterface.h"
Laurent Montel's avatar
Laurent Montel committed
34
#include "editor/plugininterface/kmailplugineditorconverttextmanagerinterface.h"
35
#include "editor/plugininterface/kmailplugingrammareditormanagerinterface.h"
Sandro Knauß's avatar
Sandro Knauß committed
36 37 38 39 40 41 42
#include "editor/potentialphishingemail/potentialphishingemailjob.h"
#include "editor/potentialphishingemail/potentialphishingemailwarning.h"
#include "editor/warningwidgets/incorrectidentityfolderwarning.h"
#include "job/addressvalidationjob.h"
#include "job/createnewcontactjob.h"
#include "job/saveasfilejob.h"
#include "job/savedraftjob.h"
Laurent Montel's avatar
Laurent Montel committed
43
#include "job/dndfromarkjob.h"
Sandro Knauß's avatar
Sandro Knauß committed
44 45 46 47 48
#include "kconfigwidgets_version.h"
#include "kmail_debug.h"
#include "kmcommands.h"
#include "kmcomposercreatenewcomposerjob.h"
#include "kmcomposerglobalaction.h"
Laurent Montel's avatar
Laurent Montel committed
49
#include "kmcomposerupdatetemplatejob.h"
50
#include "kmkernel.h"
51
#include "kmmainwidget.h"
Sandro Knauß's avatar
Sandro Knauß committed
52
#include "kmmainwin.h"
53
#include "mailcomposeradaptor.h" // TODO port all D-Bus stuff...
Sandro Knauß's avatar
Sandro Knauß committed
54
#include "settings/kmailsettings.h"
Laurent Montel's avatar
Laurent Montel committed
55
#include "templatesconfiguration_kfg.h"
Sandro Knauß's avatar
Sandro Knauß committed
56 57
#include "util.h"
#include "validatesendmailshortcut.h"
Laurent Montel's avatar
Laurent Montel committed
58 59
#include "warningwidgets/attachmentmissingwarning.h"
#include "warningwidgets/externaleditorwarning.h"
Laurent Montel's avatar
Laurent Montel committed
60
#include "widgets/cryptostateindicatorwidget.h"
61
#include "widgets/kactionmenutransport.h"
62
#include "undosend/undosendmanager.h"
Sandro Knauß's avatar
Sandro Knauß committed
63 64 65 66 67 68
#include <Akonadi/Contact/ContactGroupExpandJob>
#include <Akonadi/KMime/MessageFlags>
#include <Akonadi/KMime/MessageStatus>
#include <AkonadiCore/ItemFetchJob>
#include <AkonadiCore/Monitor>
#include <AkonadiCore/changerecorder.h>
Laurent Montel's avatar
Laurent Montel committed
69

Sandro Knauß's avatar
Sandro Knauß committed
70
#include <FollowupReminder/FollowUpReminderUtil>
Laurent Montel's avatar
Laurent Montel committed
71

Sandro Knauß's avatar
Sandro Knauß committed
72
#include <KContacts/VCardConverter>
Laurent Montel's avatar
Laurent Montel committed
73

Sandro Knauß's avatar
Sandro Knauß committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
#include <KIdentityManagement/Identity>
#include <KIdentityManagement/IdentityCombo>
#include <KIdentityManagement/IdentityManager>
#include <KIdentityManagement/Signature>

#include <KMime/Message>

#include <KPIMTextEdit/EditorUtil>
#include <KPIMTextEdit/RichTextComposerActions>
#include <KPIMTextEdit/RichTextComposerControler>
#include <KPIMTextEdit/RichTextComposerImages>
#include <KPIMTextEdit/RichTextEditorWidget>
#include <KPIMTextEdit/RichTextExternalComposer>

#include <Libkdepim/ProgressStatusBarWidget>
#include <Libkdepim/StatusbarProgressWidget>
Laurent Montel's avatar
Laurent Montel committed
90 91

#ifndef QT_NO_CURSOR
92
#include <Libkdepim/KCursorSaver>
Laurent Montel's avatar
Laurent Montel committed
93 94
#endif

Sandro Knauß's avatar
Sandro Knauß committed
95 96 97 98 99 100 101
#include <Libkleo/KeySelectionDialog>
#include <Libkleo/ProgressDialog>

#include <MailCommon/FolderCollectionMonitor>
#include <MailCommon/FolderRequester>
#include <MailCommon/FolderSettings>
#include <MailCommon/MailKernel>
Laurent Montel's avatar
Laurent Montel committed
102
#include <MailCommon/SnippetTreeView>
Laurent Montel's avatar
Laurent Montel committed
103 104
#include <MailCommon/SnippetsManager>

Sandro Knauß's avatar
Sandro Knauß committed
105 106 107 108 109
#include <MailTransport/Transport>
#include <MailTransport/TransportComboBox>
#include <MailTransport/TransportManager>

#include <MessageComposer/AttachmentModel>
Laurent Montel's avatar
Laurent Montel committed
110
#include <MessageComposer/Composer>
Sandro Knauß's avatar
Sandro Knauß committed
111 112 113
#include <MessageComposer/ComposerLineEdit>
#include <MessageComposer/FollowUpReminderSelectDateDialog>
#include <MessageComposer/FollowupReminderCreateJob>
Laurent Montel's avatar
Laurent Montel committed
114 115
#include <MessageComposer/GlobalPart>
#include <MessageComposer/InfoPart>
Sandro Knauß's avatar
Sandro Knauß committed
116 117 118
#include <MessageComposer/InsertTextFileJob>
#include <MessageComposer/Kleo_Util>
#include <MessageComposer/MessageComposerSettings>
Laurent Montel's avatar
Laurent Montel committed
119
#include <MessageComposer/MessageHelper>
Sandro Knauß's avatar
Sandro Knauß committed
120 121
#include <MessageComposer/PluginEditorCheckBeforeSendParams>
#include <MessageComposer/PluginEditorInterface>
Laurent Montel's avatar
Laurent Montel committed
122
#include <MessageComposer/PluginActionType>
Sandro Knauß's avatar
Sandro Knauß committed
123
#include <MessageComposer/RichTextComposerSignatures>
Laurent Montel's avatar
Laurent Montel committed
124
#include <MessageComposer/SignatureController>
Sandro Knauß's avatar
Sandro Knauß committed
125 126
#include <MessageComposer/TextPart>
#include <MessageComposer/Util>
127
#include <MessageComposer/StatusBarLabelToggledState>
128 129
#include <MessageComposer/ConvertSnippetVariablesJob>
#include <MessageComposer/ComposerViewInterface>
130

Laurent Montel's avatar
Laurent Montel committed
131
#include <Sonnet/DictionaryComboBox>
Laurent Montel's avatar
Laurent Montel committed
132

Laurent Montel's avatar
Laurent Montel committed
133
#include <MessageCore/AttachmentPart>
Laurent Montel's avatar
Laurent Montel committed
134
#include <MessageCore/MessageCoreSettings>
Laurent Montel's avatar
Laurent Montel committed
135
#include <MessageCore/NodeHelper>
Sandro Knauß's avatar
Sandro Knauß committed
136
#include <MessageCore/StringUtil>
Thomas McGuire's avatar
Thomas McGuire committed
137

Sandro Knauß's avatar
Sandro Knauß committed
138 139
#include <MessageViewer/MessageViewerSettings>
#include <MessageViewer/Stl_Util>
140

Sandro Knauß's avatar
Sandro Knauß committed
141 142 143
#include <MimeTreeParser/NodeHelper>
#include <MimeTreeParser/ObjectTreeParser>
#include <MimeTreeParser/SimpleObjectTreeSource>
144

Sandro Knauß's avatar
Sandro Knauß committed
145 146 147
#include <PimCommon/CustomToolsWidgetng>
#include <PimCommon/KActionMenuChangeCase>
#include <PimCommon/LineEditWithAutoCorrection>
148
#include <PimCommon/CustomToolsPluginManager>
Laurent Montel's avatar
Laurent Montel committed
149

Sandro Knauß's avatar
Sandro Knauß committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
#include <SendLater/SendLaterDialog>
#include <SendLater/SendLaterInfo>
#include <SendLater/SendLaterUtil>

#include <TemplateParser/TemplateParserJob>
#include <TemplateParser/TemplatesConfiguration>

#include <QGpgME/Protocol>
#include <QGpgME/ExportJob>
#include <QGpgME/KeyForMailboxJob>

// KDE Frameworks includes
#include <KActionCollection>
#include <KActionMenu>
#include <KCharsets>
#include <KConfigGroup>
#include <KEditToolBar>
167
#include <KEmailAddress>
168
#include <KEncodingFileDialog>
Sandro Knauß's avatar
Sandro Knauß committed
169
#include <KIO/JobUiDelegate>
170
#include <KIconUtils>
Sandro Knauß's avatar
Sandro Knauß committed
171 172 173 174 175 176 177 178
#include <KMessageBox>
#include <KRecentFilesAction>
#include <KRun>
#include <KShortcutsDialog>
#include <KSplitterCollapserButton>
#include <KStandardShortcut>
#include <KToggleAction>
#include <KToolBar>
179
#include <QDBusConnection>
Sandro Knauß's avatar
Sandro Knauß committed
180
#include <sonnet_version.h>
Laurent Montel's avatar
Laurent Montel committed
181
#include <KXMLGUIFactory>
Volker Krause's avatar
Volker Krause committed
182
// Qt includes
183
#include <QAction>
184
#include <QApplication>
185
#include <QCheckBox>
Sandro Knauß's avatar
Sandro Knauß committed
186
#include <QClipboard>
187
#include <QFontDatabase>
Sandro Knauß's avatar
Sandro Knauß committed
188 189 190
#include <QInputDialog>
#include <QMenu>
#include <QMimeData>
191
#include <QPointer>
Sandro Knauß's avatar
Sandro Knauß committed
192 193 194 195
#include <QShortcut>
#include <QSplitter>
#include <QStandardPaths>
#include <QStatusBar>
196
#include <QMenuBar>
Laurent Montel's avatar
Laurent Montel committed
197
#include <MessageComposer/PluginEditorConverterInitialData>
Laurent Montel's avatar
Laurent Montel committed
198
#include <MessageComposer/PluginEditorConverterBeforeConvertingData>
199 200 201 202

// GPGME
#include <gpgme++/keylistresult.h>
#include <gpgme++/key.h>
Volker Krause's avatar
Volker Krause committed
203

Laurent Montel's avatar
Laurent Montel committed
204
using Sonnet::DictionaryComboBox;
Thomas McGuire's avatar
Thomas McGuire committed
205 206
using MailTransport::TransportManager;
using MailTransport::Transport;
Volker Krause's avatar
Volker Krause committed
207

208 209
Q_DECLARE_METATYPE(MessageComposer::Recipient::Ptr)

Laurent Montel's avatar
Laurent Montel committed
210
KMail::Composer *KMail::makeComposer(const KMime::Message::Ptr &msg, bool lastSignState, bool lastEncryptState, Composer::TemplateContext context, uint identity, const QString &textSelection,
Laurent Montel's avatar
Laurent Montel committed
211 212
                                     const QString &customTemplate)
{
Laurent Montel's avatar
Laurent Montel committed
213
    return KMComposerWin::create(msg, lastSignState, lastEncryptState, context, identity, textSelection, customTemplate);
Volker Krause's avatar
Volker Krause committed
214 215
}

Laurent Montel's avatar
Laurent Montel committed
216
KMail::Composer *KMComposerWin::create(const KMime::Message::Ptr &msg, bool lastSignState, bool lastEncryptState, Composer::TemplateContext context, uint identity, const QString &textSelection, const QString &customTemplate)
Laurent Montel's avatar
Laurent Montel committed
217
{
Laurent Montel's avatar
Laurent Montel committed
218
    return new KMComposerWin(msg, lastSignState, lastEncryptState, context, identity, textSelection, customTemplate);
Volker Krause's avatar
Volker Krause committed
219 220
}

Laurent Montel's avatar
Laurent Montel committed
221
int KMComposerWin::s_composerNumber = 0;
Volker Krause's avatar
Volker Krause committed
222

Laurent Montel's avatar
Laurent Montel committed
223
KMComposerWin::KMComposerWin(const KMime::Message::Ptr &aMsg, bool lastSignState, bool lastEncryptState, Composer::TemplateContext context, uint id, const QString &textSelection, const QString &customTemplate)
Laurent Montel's avatar
Laurent Montel committed
224 225 226 227 228 229
    : KMail::Composer(QStringLiteral("kmail-composer#"))
    , mTextSelection(textSelection)
    , mCustomTemplate(customTemplate)
    , mFolder(Akonadi::Collection(-1))
    , mId(id)
    , mContext(context)
Laurent Montel's avatar
Laurent Montel committed
230
{
Laurent Montel's avatar
Laurent Montel committed
231
    mGlobalAction = new KMComposerGlobalAction(this, this);
Laurent Montel's avatar
Laurent Montel committed
232 233
    mComposerBase = new MessageComposer::ComposerViewBase(this, this);
    mComposerBase->setIdentityManager(kmkernel->identityManager());
Laurent Montel's avatar
Laurent Montel committed
234

Laurent Montel's avatar
Laurent Montel committed
235
    mPluginEditorManagerInterface = new KMailPluginEditorManagerInterface(this);
Laurent Montel's avatar
Laurent Montel committed
236
    connect(mPluginEditorManagerInterface, &KMailPluginEditorManagerInterface::message, this, &KMComposerWin::slotMessage);
237
    connect(mPluginEditorManagerInterface, &KMailPluginEditorManagerInterface::insertText, this, &KMComposerWin::slotEditorPluginInsertText);
Laurent Montel's avatar
Laurent Montel committed
238
    mPluginEditorCheckBeforeSendManagerInterface = new KMailPluginEditorCheckBeforeSendManagerInterface(this);
Laurent Montel's avatar
Laurent Montel committed
239
    mPluginEditorInitManagerInterface = new KMailPluginEditorInitManagerInterface(this);
Laurent Montel's avatar
Laurent Montel committed
240
    mPluginEditorConvertTextManagerInterface = new KMailPluginEditorConvertTextManagerInterface(this);
Laurent Montel's avatar
Laurent Montel committed
241

242 243
    mPluginEditorGrammarManagerInterface = new KMailPluginGrammarEditorManagerInterface(this);

Laurent Montel's avatar
Laurent Montel committed
244 245 246 247 248
    connect(mComposerBase, &MessageComposer::ComposerViewBase::disableHtml, this, &KMComposerWin::disableHtml);
    connect(mComposerBase, &MessageComposer::ComposerViewBase::enableHtml, this, &KMComposerWin::enableHtml);
    connect(mComposerBase, &MessageComposer::ComposerViewBase::failed, this, &KMComposerWin::slotSendFailed);
    connect(mComposerBase, &MessageComposer::ComposerViewBase::sentSuccessfully, this, &KMComposerWin::slotSendSuccessful);
    connect(mComposerBase, &MessageComposer::ComposerViewBase::modified, this, &KMComposerWin::setModified);
Laurent Montel's avatar
Laurent Montel committed
249

Laurent Montel's avatar
Laurent Montel committed
250
    (void)new MailcomposerAdaptor(this);
Laurent Montel's avatar
Laurent Montel committed
251 252
    mdbusObjectPath = QLatin1String("/Composer_") + QString::number(++s_composerNumber);
    QDBusConnection::sessionBus().registerObject(mdbusObjectPath, this);
Laurent Montel's avatar
Laurent Montel committed
253

Laurent Montel's avatar
Laurent Montel committed
254
    MessageComposer::SignatureController *sigController = new MessageComposer::SignatureController(this);
Laurent Montel's avatar
Laurent Montel committed
255
    connect(sigController, &MessageComposer::SignatureController::enableHtml, this, &KMComposerWin::enableHtml);
Laurent Montel's avatar
Laurent Montel committed
256
    mComposerBase->setSignatureController(sigController);
Laurent Montel's avatar
Laurent Montel committed
257

Laurent Montel's avatar
Laurent Montel committed
258
    if (!kmkernel->xmlGuiInstanceName().isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
259
        setComponentName(kmkernel->xmlGuiInstanceName(), i18n("KMail2"));
Laurent Montel's avatar
Laurent Montel committed
260
    }
Laurent Montel's avatar
Laurent Montel committed
261
    mMainWidget = new QWidget(this);
Laurent Montel's avatar
Laurent Montel committed
262
    // splitter between the headers area and the actual editor
Laurent Montel's avatar
Laurent Montel committed
263
    mHeadersToEditorSplitter = new QSplitter(Qt::Vertical, mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
264
    mHeadersToEditorSplitter->setObjectName(QStringLiteral("mHeadersToEditorSplitter"));
Laurent Montel's avatar
Laurent Montel committed
265 266 267 268 269
    mHeadersToEditorSplitter->setChildrenCollapsible(false);
    mHeadersArea = new QWidget(mHeadersToEditorSplitter);
    mHeadersArea->setSizePolicy(mHeadersToEditorSplitter->sizePolicy().horizontalPolicy(),
                                QSizePolicy::Expanding);
    mHeadersToEditorSplitter->addWidget(mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
270 271 272
    const QList<int> defaultSizes{
        0
    };
Laurent Montel's avatar
Laurent Montel committed
273
    mHeadersToEditorSplitter->setSizes(defaultSizes);
Laurent Montel's avatar
Laurent Montel committed
274

Laurent Montel's avatar
Laurent Montel committed
275
    QVBoxLayout *v = new QVBoxLayout(mMainWidget);
276
    v->setContentsMargins(0, 0, 0, 0);
Laurent Montel's avatar
Laurent Montel committed
277 278
    v->addWidget(mHeadersToEditorSplitter);
    KIdentityManagement::IdentityCombo *identity = new KIdentityManagement::IdentityCombo(kmkernel->identityManager(),
Laurent Montel's avatar
Laurent Montel committed
279
                                                                                          mHeadersArea);
280
    identity->setCurrentIdentity(mId);
281
    connect(identity, &KIdentityManagement::IdentityCombo::identityDeleted, this, &KMComposerWin::slotIdentityDeleted);
282
    connect(identity, &KIdentityManagement::IdentityCombo::invalidIdentity, this, &KMComposerWin::slotInvalidIdentity);
Laurent Montel's avatar
Laurent Montel committed
283
    mComposerBase->setIdentityCombo(identity);
Laurent Montel's avatar
Laurent Montel committed
284

Laurent Montel's avatar
Laurent Montel committed
285
    sigController->setIdentityCombo(identity);
Laurent Montel's avatar
Laurent Montel committed
286 287
    sigController->suspend(); // we have to do identity change tracking ourselves due to the template code

Laurent Montel's avatar
Laurent Montel committed
288
    Sonnet::DictionaryComboBox *dictionaryCombo = new DictionaryComboBox(mHeadersArea);
289
    dictionaryCombo->setToolTip(i18n("Select the dictionary to use when spell-checking this message"));
290
    mComposerBase->setDictionary(dictionaryCombo);
Laurent Montel's avatar
Laurent Montel committed
291

Laurent Montel's avatar
Laurent Montel committed
292 293 294
    mFccFolder = new MailCommon::FolderRequester(mHeadersArea);
    mFccFolder->setNotAllowToCreateNewFolder(true);
    mFccFolder->setMustBeReadWrite(true);
Laurent Montel's avatar
Laurent Montel committed
295

Laurent Montel's avatar
Laurent Montel committed
296
    mFccFolder->setToolTip(i18n("Select the sent-mail folder where a copy of this message will be saved"));
Laurent Montel's avatar
Laurent Montel committed
297
    connect(mFccFolder, &MailCommon::FolderRequester::folderChanged, this, &KMComposerWin::slotFccFolderChanged);
Laurent Montel's avatar
Laurent Montel committed
298
    connect(mFccFolder, &MailCommon::FolderRequester::invalidFolder, this, &KMComposerWin::slotFccIsInvalid);
Laurent Montel's avatar
Laurent Montel committed
299

Laurent Montel's avatar
Laurent Montel committed
300 301 302
    MailTransport::TransportComboBox *transport = new MailTransport::TransportComboBox(mHeadersArea);
    transport->setToolTip(i18n("Select the outgoing account to use for sending this message"));
    mComposerBase->setTransportCombo(transport);
Laurent Montel's avatar
Laurent Montel committed
303
    connect(transport, qOverload<int>(&MailTransport::TransportComboBox::activated), this, &KMComposerWin::slotTransportChanged);
304
    connect(transport, &MailTransport::TransportComboBox::transportRemoved, this, &KMComposerWin::slotTransportRemoved);
Laurent Montel's avatar
Laurent Montel committed
305
    mEdtFrom = new MessageComposer::ComposerLineEdit(false, mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
306
    mEdtFrom->setObjectName(QStringLiteral("fromLine"));
Laurent Montel's avatar
Laurent Montel committed
307 308
    mEdtFrom->setRecentAddressConfig(MessageComposer::MessageComposerSettings::self()->config());
    mEdtFrom->setToolTip(i18n("Set the \"From:\" email address for this message"));
Laurent Montel's avatar
Laurent Montel committed
309

Laurent Montel's avatar
Laurent Montel committed
310 311
    MessageComposer::RecipientsEditor *recipientsEditor = new MessageComposer::RecipientsEditor(mHeadersArea);
    recipientsEditor->setRecentAddressConfig(MessageComposer::MessageComposerSettings::self()->config());
Laurent Montel's avatar
Laurent Montel committed
312 313
    connect(recipientsEditor, &MessageComposer::RecipientsEditor::completionModeChanged, this, &KMComposerWin::slotCompletionModeChanged);
    connect(recipientsEditor, &MessageComposer::RecipientsEditor::sizeHintChanged, this, &KMComposerWin::recipientEditorSizeHintChanged);
314
    connect(recipientsEditor, &MessageComposer::RecipientsEditor::lineAdded, this, &KMComposerWin::slotRecipientEditorLineAdded);
Laurent Montel's avatar
Laurent Montel committed
315
    mComposerBase->setRecipientsEditor(recipientsEditor);
Laurent Montel's avatar
Laurent Montel committed
316

Laurent Montel's avatar
Laurent Montel committed
317
    mEdtSubject = new PimCommon::LineEditWithAutoCorrection(mHeadersArea, QStringLiteral("kmail2rc"));
Laurent Montel's avatar
Laurent Montel committed
318
    mEdtSubject->setActivateLanguageMenu(false);
Laurent Montel's avatar
Laurent Montel committed
319
    mEdtSubject->setToolTip(i18n("Set a subject for this message"));
Laurent Montel's avatar
Laurent Montel committed
320
    mEdtSubject->setAutocorrection(KMKernel::self()->composerAutoCorrection());
Laurent Montel's avatar
Laurent Montel committed
321 322 323 324 325 326
    mLblIdentity = new QLabel(i18n("&Identity:"), mHeadersArea);
    mDictionaryLabel = new QLabel(i18n("&Dictionary:"), mHeadersArea);
    mLblFcc = new QLabel(i18n("&Sent-Mail folder:"), mHeadersArea);
    mLblTransport = new QLabel(i18n("&Mail transport:"), mHeadersArea);
    mLblFrom = new QLabel(i18nc("sender address field", "&From:"), mHeadersArea);
    mLblSubject = new QLabel(i18nc("@label:textbox Subject of email.", "S&ubject:"), mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
327
    mShowHeaders = KMailSettings::self()->headers();
Laurent Montel's avatar
Laurent Montel committed
328
    mDone = false;
Laurent Montel's avatar
Laurent Montel committed
329 330
    mGrid = nullptr;
    mFixedFontAction = nullptr;
Laurent Montel's avatar
Laurent Montel committed
331
    // the attachment view is separated from the editor by a splitter
Laurent Montel's avatar
Laurent Montel committed
332
    mSplitter = new QSplitter(Qt::Vertical, mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
333
    mSplitter->setObjectName(QStringLiteral("mSplitter"));
Laurent Montel's avatar
Laurent Montel committed
334 335
    mSplitter->setChildrenCollapsible(false);
    mSnippetSplitter = new QSplitter(Qt::Horizontal, mSplitter);
Laurent Montel's avatar
Laurent Montel committed
336
    mSnippetSplitter->setObjectName(QStringLiteral("mSnippetSplitter"));
Laurent Montel's avatar
Laurent Montel committed
337 338 339
    mSplitter->addWidget(mSnippetSplitter);

    QWidget *editorAndCryptoStateIndicators = new QWidget(mSplitter);
Laurent Montel's avatar
Laurent Montel committed
340
    mCryptoStateIndicatorWidget = new CryptoStateIndicatorWidget(this);
Laurent Montel's avatar
Laurent Montel committed
341
    mCryptoStateIndicatorWidget->setShowAlwaysIndicator(KMailSettings::self()->showCryptoLabelIndicator());
Laurent Montel's avatar
Laurent Montel committed
342

343
    QVBoxLayout *vbox = new QVBoxLayout(editorAndCryptoStateIndicators);
344
    vbox->setContentsMargins(0, 0, 0, 0);
345

346 347 348 349 350 351 352 353 354
    mPotentialPhishingEmailWarning = new PotentialPhishingEmailWarning(this);
    connect(mPotentialPhishingEmailWarning, &PotentialPhishingEmailWarning::sendNow, this, &KMComposerWin::slotCheckSendNowStep2);
    vbox->addWidget(mPotentialPhishingEmailWarning);

    mAttachmentMissing = new AttachmentMissingWarning(this);
    connect(mAttachmentMissing, &AttachmentMissingWarning::attachMissingFile, this, &KMComposerWin::slotAttachMissingFile);
    connect(mAttachmentMissing, &AttachmentMissingWarning::explicitClosedMissingAttachment, this, &KMComposerWin::slotExplicitClosedMissingAttachment);
    vbox->addWidget(mAttachmentMissing);

Laurent Montel's avatar
Laurent Montel committed
355 356
    KMComposerEditorNg *composerEditorNg = new KMComposerEditorNg(this, mCryptoStateIndicatorWidget);
    mRichTextEditorwidget = new KPIMTextEdit::RichTextEditorWidget(composerEditorNg, mCryptoStateIndicatorWidget);
Laurent Montel's avatar
Laurent Montel committed
357

358
    connect(composerEditorNg, &KMComposerEditorNg::insertEmoticon, mGlobalAction, &KMComposerGlobalAction::slotInsertEmoticon);
359
    //Don't use new connect api here. It crashes
360
    connect(composerEditorNg, SIGNAL(textChanged()), this, SLOT(slotEditorTextChanged()));
361
    connect(composerEditorNg, &KMComposerEditorNg::selectionChanged, this, &KMComposerWin::slotSelectionChanged);
362
    //connect(editor, &KMComposerEditor::textChanged, this, &KMComposeWin::slotEditorTextChanged);
Laurent Montel's avatar
Laurent Montel committed
363
    mComposerBase->setEditor(composerEditorNg);
364 365 366
    mIncorrectIdentityFolderWarning = new IncorrectIdentityFolderWarning(this);
    vbox->addWidget(mIncorrectIdentityFolderWarning);

Laurent Montel's avatar
Laurent Montel committed
367
    vbox->addWidget(mCryptoStateIndicatorWidget);
368
    vbox->addWidget(mRichTextEditorwidget);
Laurent Montel's avatar
Laurent Montel committed
369

Laurent Montel's avatar
Laurent Montel committed
370 371
    mSnippetSplitter->insertWidget(0, editorAndCryptoStateIndicators);
    mSnippetSplitter->setOpaqueResize(true);
Laurent Montel's avatar
Laurent Montel committed
372
    sigController->setEditor(composerEditorNg);
Laurent Montel's avatar
Laurent Montel committed
373

Laurent Montel's avatar
Laurent Montel committed
374
    mHeadersToEditorSplitter->addWidget(mSplitter);
Laurent Montel's avatar
Laurent Montel committed
375
    composerEditorNg->setAcceptDrops(true);
Laurent Montel's avatar
Laurent Montel committed
376 377
    connect(sigController, &MessageComposer::SignatureController::signatureAdded,
            mComposerBase->editor()->externalComposer(), &KPIMTextEdit::RichTextExternalComposer::startExternalEditor);
Laurent Montel's avatar
Laurent Montel committed
378

Laurent Montel's avatar
Laurent Montel committed
379
    connect(dictionaryCombo, &Sonnet::DictionaryComboBox::dictionaryChanged, this, &KMComposerWin::slotSpellCheckingLanguage);
Laurent Montel's avatar
Laurent Montel committed
380

Laurent Montel's avatar
Laurent Montel committed
381 382 383 384
    connect(composerEditorNg, &KMComposerEditorNg::languageChanged, this, &KMComposerWin::slotDictionaryLanguageChanged);
    connect(composerEditorNg, &KMComposerEditorNg::spellCheckStatus, this, &KMComposerWin::slotSpellCheckingStatus);
    connect(composerEditorNg, &KMComposerEditorNg::insertModeChanged, this, &KMComposerWin::slotOverwriteModeChanged);
    connect(composerEditorNg, &KMComposerEditorNg::spellCheckingFinished, this, &KMComposerWin::slotDelayedCheckSendNow);
Laurent Montel's avatar
Laurent Montel committed
385
    mSnippetWidget = new MailCommon::SnippetTreeView(actionCollection(), mSnippetSplitter);
Laurent Montel's avatar
Laurent Montel committed
386
    connect(mSnippetWidget, &MailCommon::SnippetTreeView::insertSnippetInfo, this, &KMComposerWin::insertSnippetInfo);
Laurent Montel's avatar
Laurent Montel committed
387
    connect(composerEditorNg, &KMComposerEditorNg::insertSnippet, mSnippetWidget->snippetsManager(), &MailCommon::SnippetsManager::insertSnippet);
Laurent Montel's avatar
Laurent Montel committed
388
    mSnippetWidget->setVisible(KMailSettings::self()->showSnippetManager());
Laurent Montel's avatar
Laurent Montel committed
389 390
    mSnippetSplitter->addWidget(mSnippetWidget);
    mSnippetSplitter->setCollapsible(0, false);
391
    mSnippetSplitterCollapser = new KSplitterCollapserButton(mSnippetWidget, mSnippetSplitter);
Laurent Montel's avatar
Laurent Montel committed
392
    mSnippetSplitterCollapser->setVisible(KMailSettings::self()->showSnippetManager());
Laurent Montel's avatar
Laurent Montel committed
393

Laurent Montel's avatar
Laurent Montel committed
394
    mSplitter->setOpaqueResize(true);
Laurent Montel's avatar
Laurent Montel committed
395

Laurent Montel's avatar
Laurent Montel committed
396
    setWindowTitle(i18nc("@title:window", "Composer"));
Laurent Montel's avatar
Laurent Montel committed
397
    setMinimumSize(200, 200);
Laurent Montel's avatar
Laurent Montel committed
398

399 400
    mCustomToolsWidget = new PimCommon::CustomToolsWidgetNg(this);
    mCustomToolsWidget->initializeView(actionCollection(), PimCommon::CustomToolsPluginManager::self()->pluginsList());
Laurent Montel's avatar
Laurent Montel committed
401
    mSplitter->addWidget(mCustomToolsWidget);
Laurent Montel's avatar
Laurent Montel committed
402
    connect(mCustomToolsWidget, &PimCommon::CustomToolsWidgetNg::insertText, this, &KMComposerWin::slotInsertShortUrl);
Laurent Montel's avatar
Laurent Montel committed
403

Laurent Montel's avatar
Laurent Montel committed
404 405
    MessageComposer::AttachmentModel *attachmentModel = new MessageComposer::AttachmentModel(this);
    KMail::AttachmentView *attachmentView = new KMail::AttachmentView(attachmentModel, mSplitter);
Laurent Montel's avatar
Laurent Montel committed
406
    attachmentView->hideIfEmpty();
Laurent Montel's avatar
Laurent Montel committed
407
    connect(attachmentView, &KMail::AttachmentView::modified, this, &KMComposerWin::setModified);
Laurent Montel's avatar
Laurent Montel committed
408
    KMail::AttachmentController *attachmentController = new KMail::AttachmentController(attachmentModel, attachmentView, this);
Laurent Montel's avatar
Laurent Montel committed
409

Laurent Montel's avatar
Laurent Montel committed
410 411
    mComposerBase->setAttachmentModel(attachmentModel);
    mComposerBase->setAttachmentController(attachmentController);
Laurent Montel's avatar
Laurent Montel committed
412

Laurent Montel's avatar
Laurent Montel committed
413
    if (KMailSettings::self()->showForgottenAttachmentWarning()) {
Laurent Montel's avatar
Laurent Montel committed
414 415 416 417
        mVerifyMissingAttachment = new QTimer(this);
        mVerifyMissingAttachment->setSingleShot(true);
        mVerifyMissingAttachment->setInterval(1000 * 5);
        connect(mVerifyMissingAttachment, &QTimer::timeout, this, &KMComposerWin::slotVerifyMissingAttachmentTimeout);
418
    }
Laurent Montel's avatar
Laurent Montel committed
419
    connect(attachmentController, &KMail::AttachmentController::fileAttached, mAttachmentMissing, &AttachmentMissingWarning::slotFileAttached);
Laurent Montel's avatar
Laurent Montel committed
420 421 422 423

    mExternalEditorWarning = new ExternalEditorWarning(this);
    v->addWidget(mExternalEditorWarning);

Laurent Montel's avatar
Laurent Montel committed
424 425
    mPluginEditorManagerInterface->setParentWidget(this);
    mPluginEditorManagerInterface->setRichTextEditor(mRichTextEditorwidget->editor());
Laurent Montel's avatar
Laurent Montel committed
426
    mPluginEditorManagerInterface->setActionCollection(actionCollection());
Laurent Montel's avatar
Laurent Montel committed
427
    mPluginEditorManagerInterface->setComposerInterface(mComposerBase);
Laurent Montel's avatar
Laurent Montel committed
428

Laurent Montel's avatar
Laurent Montel committed
429 430
    mPluginEditorCheckBeforeSendManagerInterface->setParentWidget(this);

Laurent Montel's avatar
Laurent Montel committed
431
    mPluginEditorInitManagerInterface->setParentWidget(this);
Laurent Montel's avatar
Laurent Montel committed
432
    mPluginEditorInitManagerInterface->setRichTextEditor(composerEditorNg);
Laurent Montel's avatar
Laurent Montel committed
433

Laurent Montel's avatar
Laurent Montel committed
434 435
    mPluginEditorConvertTextManagerInterface->setParentWidget(this);
    mPluginEditorConvertTextManagerInterface->setActionCollection(actionCollection());
436
    mPluginEditorConvertTextManagerInterface->setRichTextEditor(composerEditorNg);
Laurent Montel's avatar
Laurent Montel committed
437

438 439 440 441 442
    mPluginEditorGrammarManagerInterface->setParentWidget(this);
    mPluginEditorGrammarManagerInterface->setActionCollection(actionCollection());
    mPluginEditorGrammarManagerInterface->setRichTextEditor(composerEditorNg);
    mPluginEditorGrammarManagerInterface->setCustomToolsWidget(mCustomToolsWidget);

Laurent Montel's avatar
Laurent Montel committed
443 444 445 446
    setupStatusBar(attachmentView->widget());
    setupActions();
    setupEditor();
    rethinkFields();
447 448
    readConfig();

Laurent Montel's avatar
Laurent Montel committed
449
    updateSignatureAndEncryptionStateIndicators();
Laurent Montel's avatar
Laurent Montel committed
450

Laurent Montel's avatar
Laurent Montel committed
451
    applyMainWindowSettings(KMKernel::self()->config()->group("Composer"));
Laurent Montel's avatar
Laurent Montel committed
452

453
    mUpdateWindowTitleConnection = connect(mEdtSubject, &PimCommon::LineEditWithAutoCorrection::textChanged, this, &KMComposerWin::slotUpdateWindowTitle);
Laurent Montel's avatar
Laurent Montel committed
454
    mIdentityConnection = connect(identity, &KIdentityManagement::IdentityCombo::identityChanged, [this](uint val) {
Laurent Montel's avatar
Laurent Montel committed
455
        slotIdentityChanged(val);
Laurent Montel's avatar
Laurent Montel committed
456
    });
Laurent Montel's avatar
Laurent Montel committed
457
    connect(kmkernel->identityManager(), qOverload<uint>(&KIdentityManagement::IdentityManager::changed), this, [this](uint val) {
458 459 460
        if (mComposerBase->identityCombo()->currentIdentity() == val) {
            slotIdentityChanged(val);
        }
Laurent Montel's avatar
Laurent Montel committed
461
    });
Laurent Montel's avatar
Laurent Montel committed
462

Laurent Montel's avatar
Laurent Montel committed
463 464 465
    connect(mEdtFrom, &MessageComposer::ComposerLineEdit::completionModeChanged, this, &KMComposerWin::slotCompletionModeChanged);
    connect(kmkernel->folderCollectionMonitor(), &Akonadi::Monitor::collectionRemoved, this, &KMComposerWin::slotFolderRemoved);
    connect(kmkernel, &KMKernel::configChanged, this, &KMComposerWin::slotConfigChanged);
Laurent Montel's avatar
Laurent Montel committed
466

Laurent Montel's avatar
Laurent Montel committed
467
    mMainWidget->resize(800, 600);
Laurent Montel's avatar
Laurent Montel committed
468
    setCentralWidget(mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
469

Laurent Montel's avatar
Laurent Montel committed
470
    if (KMailSettings::self()->useHtmlMarkup()) {
Laurent Montel's avatar
Laurent Montel committed
471
        enableHtml();
Laurent Montel's avatar
Laurent Montel committed
472 473 474
    } else {
        disableHtml(MessageComposer::ComposerViewBase::LetUserConfirm);
    }
Laurent Montel's avatar
Laurent Montel committed
475

Laurent Montel's avatar
Laurent Montel committed
476
    if (KMailSettings::self()->useExternalEditor()) {
Laurent Montel's avatar
Laurent Montel committed
477 478
        composerEditorNg->setUseExternalEditor(true);
        composerEditorNg->setExternalEditorPath(KMailSettings::self()->externalEditor());
Laurent Montel's avatar
Laurent Montel committed
479 480
    }

Laurent Montel's avatar
Laurent Montel committed
481 482
    const QList<KPIM::MultiplyingLine *> lstLines = recipientsEditor->lines();
    for (KPIM::MultiplyingLine *line : lstLines) {
483 484 485
        slotRecipientEditorLineAdded(line);
    }

Laurent Montel's avatar
Laurent Montel committed
486 487
    if (aMsg) {
        setMessage(aMsg, lastSignState, lastEncryptState);
Laurent Montel's avatar
Laurent Montel committed
488 489
    }

490
    mComposerBase->recipientsEditor()->setFocusBottom();
Laurent Montel's avatar
Laurent Montel committed
491
    composerEditorNg->composerActions()->updateActionStates(); // set toolbar buttons to correct values
Laurent Montel's avatar
Laurent Montel committed
492 493 494

    mDone = true;

Laurent Montel's avatar
Laurent Montel committed
495 496
    mDummyComposer = new MessageComposer::Composer(this);
    mDummyComposer->globalPart()->setParentWidgetForGui(this);
497 498 499

    KConfigGroup grp(KMKernel::self()->config()->group("Composer"));
    setAutoSaveSettings(grp, true);
Volker Krause's avatar
Volker Krause committed
500 501
}

Laurent Montel's avatar
Laurent Montel committed
502
KMComposerWin::~KMComposerWin()
Volker Krause's avatar
Volker Krause committed
503
{
504
    disconnect(mUpdateWindowTitleConnection);
Laurent Montel's avatar
Laurent Montel committed
505 506 507
    // When we have a collection set, store the message back to that collection.
    // Note that when we save the message or sent it, mFolder is set back to 0.
    // So this for example kicks in when opening a draft and then closing the window.
Laurent Montel's avatar
Laurent Montel committed
508
    if (mFolder.isValid() && mMsg && isModified()) {
509 510
        SaveDraftJob *saveDraftJob = new SaveDraftJob(mMsg, mFolder);
        saveDraftJob->start();
Laurent Montel's avatar
Laurent Montel committed
511
    }
Volker Krause's avatar
Volker Krause committed
512

Laurent Montel's avatar
Laurent Montel committed
513
    delete mComposerBase;
Volker Krause's avatar
Volker Krause committed
514 515
}

Laurent Montel's avatar
Laurent Montel committed
516
void KMComposerWin::insertSnippetInfo(const MailCommon::SnippetInfo &info)
Laurent Montel's avatar
Laurent Montel committed
517
{
Laurent Montel's avatar
Laurent Montel committed
518 519 520 521 522
    {
        if (!info.to.isEmpty()) {
            const QStringList lst = info.to.split(QLatin1Char(','));
            for (const QString &addr : lst) {
                mComposerBase->recipientsEditor()->addRecipient(addr, MessageComposer::Recipient::To);
Laurent Montel's avatar
Laurent Montel committed
523
            }
Laurent Montel's avatar
Laurent Montel committed
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
        }
    }
    {
        if (!info.cc.isEmpty()) {
            const QStringList lst = info.cc.split(QLatin1Char(','));
            for (const QString &addr : lst) {
                mComposerBase->recipientsEditor()->addRecipient(addr, MessageComposer::Recipient::Cc);
            }
        }
    }
    {
        if (!info.bcc.isEmpty()) {
            const QStringList lst = info.bcc.split(QLatin1Char(','));
            for (const QString &addr : lst) {
                mComposerBase->recipientsEditor()->addRecipient(addr, MessageComposer::Recipient::Bcc);
            }
        }
Laurent Montel's avatar
Laurent Montel committed
541
    }
Laurent Montel's avatar
Laurent Montel committed
542 543 544 545
    {
        if (!info.attachment.isEmpty()) {
            const QStringList lst = info.attachment.split(QLatin1Char(','));
            for (const QString &attach : lst) {
Laurent Montel's avatar
Laurent Montel committed
546 547 548 549 550 551 552 553 554 555 556
                MessageComposer::ConvertSnippetVariablesJob *job = new MessageComposer::ConvertSnippetVariablesJob(this);
                job->setText(attach);
                MessageComposer::ComposerViewInterface *interface = new MessageComposer::ComposerViewInterface(mComposerBase);
                job->setComposerViewInterface(interface);
                connect(job, &MessageComposer::ConvertSnippetVariablesJob::textConverted, this, [this](const QString &str) {
                    if (!str.isEmpty()) {
                        const QUrl localUrl = QUrl::fromLocalFile(str);
                        addAttachment(localUrl, QString());
                    }
                });
                job->start();
Laurent Montel's avatar
Laurent Montel committed
557 558 559
            }
        }
    }
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
    {
        if (!info.subject.isEmpty()) {
            //Convert subject
            MessageComposer::ConvertSnippetVariablesJob *job = new MessageComposer::ConvertSnippetVariablesJob(this);
            job->setText(info.subject);
            MessageComposer::ComposerViewInterface *interface = new MessageComposer::ComposerViewInterface(mComposerBase);
            job->setComposerViewInterface(interface);
            connect(job, &MessageComposer::ConvertSnippetVariablesJob::textConverted, this, [this](const QString &str) {
                if (!str.isEmpty()) {
                    if (mComposerBase->subject().isEmpty()) { //Add subject only if we don't have subject
                        mEdtSubject->setText(str);
                    }
                }
            });
            job->start();
        }
    }
    {
        if (!info.text.isEmpty()) {
            //Convert plain text
            MessageComposer::ConvertSnippetVariablesJob *job = new MessageComposer::ConvertSnippetVariablesJob(this);
            job->setText(info.text);
            MessageComposer::ComposerViewInterface *interface = new MessageComposer::ComposerViewInterface(mComposerBase);
            job->setComposerViewInterface(interface);
            connect(job, &MessageComposer::ConvertSnippetVariablesJob::textConverted, this, [this](const QString &str) {
                mComposerBase->editor()->insertPlainText(str);
            });
            job->start();
        }
    }
Laurent Montel's avatar
Laurent Montel committed
590 591
}

Laurent Montel's avatar
Laurent Montel committed
592
void KMComposerWin::slotSpellCheckingLanguage(const QString &language)
Laurent Montel's avatar
Laurent Montel committed
593
{
Laurent Montel's avatar
Laurent Montel committed
594 595
    mComposerBase->editor()->setSpellCheckingLanguage(language);
    mEdtSubject->setSpellCheckingLanguage(language);
Laurent Montel's avatar
Laurent Montel committed
596 597
}

Laurent Montel's avatar
Laurent Montel committed
598
QString KMComposerWin::dbusObjectPath() const
Volker Krause's avatar
Volker Krause committed
599
{
Laurent Montel's avatar
Laurent Montel committed
600
    return mdbusObjectPath;
Volker Krause's avatar
Volker Krause committed
601 602
}

Laurent Montel's avatar
Laurent Montel committed
603
void KMComposerWin::slotEditorTextChanged()
Allen Winter's avatar
Allen Winter committed
604
{
Laurent Montel's avatar
Laurent Montel committed
605
    const bool textIsNotEmpty = !mComposerBase->editor()->document()->isEmpty();
Laurent Montel's avatar
Laurent Montel committed
606 607 608 609
    mFindText->setEnabled(textIsNotEmpty);
    mFindNextText->setEnabled(textIsNotEmpty);
    mReplaceText->setEnabled(textIsNotEmpty);
    mSelectAll->setEnabled(textIsNotEmpty);
Laurent Montel's avatar
Laurent Montel committed
610 611
    if (mVerifyMissingAttachment && !mVerifyMissingAttachment->isActive()) {
        mVerifyMissingAttachment->start();
612
    }
Allen Winter's avatar
Allen Winter committed
613 614
}

Laurent Montel's avatar
Laurent Montel committed
615
void KMComposerWin::send(int how)
Volker Krause's avatar
Volker Krause committed
616
{
Laurent Montel's avatar
Laurent Montel committed
617
    switch (how) {
Laurent Montel's avatar
Laurent Montel committed
618 619 620 621 622
    case 1:
        slotSendNow();
        break;
    default:
    case 0:
Laurent Montel's avatar
Laurent Montel committed
623
    // TODO: find out, what the default send method is and send it this way
Laurent Montel's avatar
Laurent Montel committed
624 625 626 627
    case 2:
        slotSendLater();
        break;
    }
Volker Krause's avatar
Volker Krause committed
628 629
}

Laurent Montel's avatar
Laurent Montel committed
630
void KMComposerWin::addAttachmentsAndSend(const QList<QUrl> &urls, const QString &comment, int how)
Volker Krause's avatar
Volker Krause committed
631
{
Laurent Montel's avatar
Laurent Montel committed
632
    const int nbUrl = urls.count();
Laurent Montel's avatar
Laurent Montel committed
633
    for (int i = 0; i < nbUrl; ++i) {
634
        mComposerBase->addAttachment(urls.at(i), comment, true);
Laurent Montel's avatar
Laurent Montel committed
635
    }
Laurent Montel's avatar
Laurent Montel committed
636

Laurent Montel's avatar
Laurent Montel committed
637
    send(how);
Volker Krause's avatar
Volker Krause committed
638 639
}

Laurent Montel's avatar
Laurent Montel committed
640
void KMComposerWin::addAttachment(const QUrl &url, const QString &comment)
Volker Krause's avatar
Volker Krause committed
641
{
642
    mComposerBase->addAttachment(url, comment, false);
Volker Krause's avatar
Volker Krause committed
643 644
}

Laurent Montel's avatar
Laurent Montel committed
645
void KMComposerWin::addAttachment(const QString &name, KMime::Headers::contentEncoding cte, const QString &charset, const QByteArray &data, const QByteArray &mimeType)
Volker Krause's avatar
Volker Krause committed
646
{
Laurent Montel's avatar
Laurent Montel committed
647 648
    Q_UNUSED(cte);
    mComposerBase->addAttachment(name, name, charset, data, mimeType);
Volker Krause's avatar
Volker Krause committed
649 650
}

Laurent Montel's avatar
Laurent Montel committed
651
void KMComposerWin::readConfig(bool reload /* = false */)
Volker Krause's avatar
Volker Krause committed
652
{
Laurent Montel's avatar
Laurent Montel committed
653 654
    mEdtFrom->setCompletionMode((KCompletion::CompletionMode)KMailSettings::self()->completionMode());
    mComposerBase->recipientsEditor()->setCompletionMode((KCompletion::CompletionMode)KMailSettings::self()->completionMode());
Laurent Montel's avatar
Laurent Montel committed
655

Laurent Montel's avatar
Laurent Montel committed
656
    if (MessageCore::MessageCoreSettings::self()->useDefaultFonts()) {
Laurent Montel's avatar
Laurent Montel committed
657 658
        mBodyFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
        mFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
Volker Krause's avatar
Volker Krause committed
659
    } else {
Laurent Montel's avatar
Laurent Montel committed
660
        mBodyFont = KMailSettings::self()->composerFont();
Laurent Montel's avatar
Laurent Montel committed
661
        mFixedFont = MessageViewer::MessageViewerSettings::self()->fixedFont();
Volker Krause's avatar
Volker Krause committed
662 663
    }

Laurent Montel's avatar
Laurent Montel committed
664
    slotUpdateFont();
Laurent Montel's avatar
Laurent Montel committed
665 666
    mEdtFrom->setFont(mBodyFont);
    mEdtSubject->setFont(mBodyFont);
Volker Krause's avatar
Volker Krause committed
667

Laurent Montel's avatar
Laurent Montel committed
668
    if (!reload) {
Laurent Montel's avatar
Laurent Montel committed
669
        QSize siz = KMailSettings::self()->composerSize();
Laurent Montel's avatar
Laurent Montel committed
670 671
        if (siz.width() < 200) {
            siz.setWidth(200);
Laurent Montel's avatar
Laurent Montel committed
672
        }
Laurent Montel's avatar
Laurent Montel committed
673 674
        if (siz.height() < 200) {
            siz.setHeight(200);
Laurent Montel's avatar
Laurent Montel committed
675
        }
Laurent Montel's avatar
Laurent Montel committed
676
        resize(siz);
Laurent Montel's avatar
Laurent Montel committed
677

Laurent Montel's avatar
Laurent Montel committed
678 679
        if (!KMailSettings::self()->snippetSplitterPosition().isEmpty()) {
            mSnippetSplitter->setSizes(KMailSettings::self()->snippetSplitterPosition());
Laurent Montel's avatar
Laurent Montel committed
680 681 682
        } else {
            QList<int> defaults;
            defaults << (int)(width() * 0.8) << (int)(width() * 0.2);
Laurent Montel's avatar
Laurent Montel committed
683
            mSnippetSplitter->setSizes(defaults);
Laurent Montel's avatar
Laurent Montel committed
684 685 686
        }
    }

Laurent Montel's avatar
Laurent Montel committed
687
    mComposerBase->identityCombo()->setCurrentIdentity(mId);
Laurent Montel's avatar
Laurent Montel committed
688
    qCDebug(KMAIL_LOG) << mComposerBase->identityCombo()->currentIdentityName();
Laurent Montel's avatar
Laurent Montel committed
689 690
    const KIdentityManagement::Identity &ident
        = kmkernel->identityManager()->identityForUoid(mId);
Volker Krause's avatar
Volker Krause committed
691

Laurent Montel's avatar
Laurent Montel committed
692
    mComposerBase->setAutoSaveInterval(KMailSettings::self()->autosaveInterval() * 1000 * 60);
693

Laurent Montel's avatar
Laurent Montel committed
694
    mComposerBase->dictionary()->setCurrentByDictionaryName(ident.dictionary());
Laurent Montel's avatar
Laurent Montel committed
695 696

    QString fccName;
Laurent Montel's avatar
Laurent Montel committed
697
    if (!ident.fcc().isEmpty()) {
698
        fccName = ident.fcc();
Laurent Montel's avatar
Laurent Montel committed
699
    }
Laurent Montel's avatar
Laurent Montel committed
700
    setFcc(fccName);
Volker Krause's avatar
Volker Krause committed
701 702
}

Laurent Montel's avatar
Laurent Montel committed
703
void KMComposerWin::writeConfig()
Laurent Montel's avatar
Laurent Montel committed
704
{
Laurent Montel's avatar
Laurent Montel committed
705
    KMailSettings::self()->setHeaders(mShowHeaders);
Laurent Montel's avatar
Laurent Montel committed
706 707
    KMailSettings::self()->setCurrentTransport(mComposerBase->transportComboBox()->currentText());
    KMailSettings::self()->setPreviousIdentity(mComposerBase->identityCombo()->currentIdentity());
Laurent Montel's avatar
Laurent Montel committed
708 709
    KMailSettings::self()->setPreviousFcc(QString::number(mFccFolder->collection().id()));
    KMailSettings::self()->setPreviousDictionary(mComposerBase->dictionary()->currentDictionaryName());
Laurent Montel's avatar
Laurent Montel committed
710
    KMailSettings::self()->setAutoSpellChecking(mAutoSpellCheckingAction->isChecked());
Laurent Montel's avatar
Laurent Montel committed
711
    MessageViewer::MessageViewerSettings::self()->setUseFixedFont(mFixedFontAction->isChecked());
Laurent Montel's avatar
Laurent Montel committed
712
    if (!mForceDisableHtml) {
Laurent Montel's avatar
Laurent Montel committed
713
        KMailSettings::self()->setUseHtmlMarkup(mComposerBase->editor()->textMode() == MessageComposer::RichTextComposerNg::Rich);
Laurent Montel's avatar
Laurent Montel committed
714
    }
Laurent Montel's avatar
Laurent Montel committed
715 716
    KMailSettings::self()->setComposerSize(size());
    KMailSettings::self()->setShowSnippetManager(mSnippetAction->isChecked());
Laurent Montel's avatar
Laurent Montel committed
717 718

    if (mSnippetAction->isChecked()) {
Laurent Montel's avatar
Laurent Montel committed
719
        KMailSettings::setSnippetSplitterPosition(mSnippetSplitter->sizes());
Laurent Montel's avatar
Laurent Montel committed
720
    }
Laurent Montel's avatar
Laurent Montel committed
721 722 723

    // make sure config changes are written to disk, cf. bug 127538
    KMKernel::self()->slotSyncConfig();
Volker Krause's avatar
Volker Krause committed
724 725
}

Laurent Montel's avatar
Laurent Montel committed
726
MessageComposer::Composer *KMComposerWin::createSimpleComposer()
727
{
Laurent Montel's avatar
Laurent Montel committed
728
    QVector< QByteArray > charsets = mCodecAction->mimeCharsets();
Laurent Montel's avatar
Laurent Montel committed
729 730
    if (!mOriginalPreferredCharset.isEmpty()) {
        charsets.insert(0, mOriginalPreferredCharset);
Laurent Montel's avatar
Laurent Montel committed
731
    }
Laurent Montel's avatar
Laurent Montel committed
732 733 734
    mComposerBase->setFrom(from());
    mComposerBase->setSubject(subject());
    mComposerBase->setCharsets(charsets);
Laurent Montel's avatar
Laurent Montel committed
735
    return mComposerBase->createSimpleComposer();
736 737
}

Laurent Montel's avatar
Laurent Montel committed
738
bool KMComposerWin::canSignEncryptAttachments() const
Laurent Montel's avatar