kmcomposerwin.cpp 127 KB
Newer Older
1 2
/*
 * This file is part of KMail.
Laurent Montel's avatar
Laurent Montel committed
3
 * Copyright (c) 2011-2016 Laurent Montel <montel@kde.org>
4
 *
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"
25 26

// KMail includes
Laurent Montel's avatar
Laurent Montel committed
27
#include "job/addressvalidationjob.h"
Laurent Montel's avatar
Laurent Montel committed
28
#include "attachment/attachmentcontroller.h"
Laurent Montel's avatar
Laurent Montel committed
29
#include <MessageComposer/AttachmentModel>
Laurent Montel's avatar
Laurent Montel committed
30
#include "attachment/attachmentview.h"
31
#include "codec/codecaction.h"
Laurent Montel's avatar
Laurent Montel committed
32
#include "MessageComposer/Kleo_Util"
33
#include "kmcommands.h"
34
#include "editor/kmcomposereditorng.h"
Laurent Montel's avatar
Laurent Montel committed
35
#include "KPIMTextEdit/RichTextComposerControler"
Laurent Montel's avatar
Laurent Montel committed
36
#include "MessageComposer/RichTextComposerSignatures"
Laurent Montel's avatar
Laurent Montel committed
37
#include <KPIMTextEdit/RichTextComposerActions>
Laurent Montel's avatar
Laurent Montel committed
38 39
#include "KPIMTextEdit/RichTextComposerImages"
#include "KPIMTextEdit/RichTextExternalComposer"
Laurent Montel's avatar
Laurent Montel committed
40
#include <KPIMTextEdit/RichTextEditorWidget>
41
#include "kmkernel.h"
Laurent Montel's avatar
Laurent Montel committed
42
#include "settings/kmailsettings.h"
43
#include "kmmainwin.h"
44
#include "kmmainwidget.h"
45
#include "mailcomposeradaptor.h" // TODO port all D-Bus stuff...
Laurent Montel's avatar
Laurent Montel committed
46
#include "messageviewer/stl_util.h"
47
#include "messagecomposer/util.h"
48
#include "MessageCore/StringUtil"
49
#include "util.h"
Laurent Montel's avatar
Laurent Montel committed
50
#include "editor/widgets/snippetwidget.h"
Laurent Montel's avatar
Laurent Montel committed
51
#include "templatesconfiguration_kfg.h"
Laurent Montel's avatar
Laurent Montel committed
52
#include "mailcommon/foldercollectionmonitor.h"
Laurent Montel's avatar
Laurent Montel committed
53
#include "mailcommon/mailkernel.h"
54
#include "custommimeheader.h"
Laurent Montel's avatar
Laurent Montel committed
55 56
#include "PimCommon/LineEditWithAutoCorrection"
#include "PimCommon/CustomToolsWidgetng"
Laurent Montel's avatar
Laurent Montel committed
57
#include "warningwidgets/attachmentmissingwarning.h"
Laurent Montel's avatar
Laurent Montel committed
58
#include "job/createnewcontactjob.h"
59
#include "job/savedraftjob.h"
Laurent Montel's avatar
Laurent Montel committed
60
#include "warningwidgets/externaleditorwarning.h"
Laurent Montel's avatar
Laurent Montel committed
61
#include "widgets/cryptostateindicatorwidget.h"
Laurent Montel's avatar
Laurent Montel committed
62
#include "validatesendmailshortcut.h"
Laurent Montel's avatar
Laurent Montel committed
63
#include "job/saveasfilejob.h"
64 65
#include "messagecomposer/followupreminderselectdatedialog.h"
#include "messagecomposer/followupremindercreatejob.h"
Laurent Montel's avatar
Laurent Montel committed
66
#include "FollowupReminder/FollowUpReminderUtil"
Laurent Montel's avatar
Laurent Montel committed
67
#include "editor/potentialphishingemail/potentialphishingemailwarning.h"
Laurent Montel's avatar
Laurent Montel committed
68
#include "kmcomposerglobalaction.h"
69
#include "widgets/kactionmenutransport.h"
70
#include "pimcommon/kactionmenuchangecase.h"
71

Laurent Montel's avatar
Laurent Montel committed
72 73
#include "Libkdepim/StatusbarProgressWidget"
#include "Libkdepim/ProgressStatusBarWidget"
Laurent Montel's avatar
Laurent Montel committed
74

Laurent Montel's avatar
Laurent Montel committed
75
#include "KPIMTextEdit/EditorUtil"
Laurent Montel's avatar
Laurent Montel committed
76 77
#include "PimCommon/StorageServiceManager"
#include "PimCommon/StorageServiceProgressManager"
Laurent Montel's avatar
Laurent Montel committed
78
#include "plugineditorinterface.h"
Laurent Montel's avatar
Laurent Montel committed
79 80
#include "editor/plugininterface/kmailplugineditormanagerinterface.h"

Laurent Montel's avatar
Laurent Montel committed
81
#include "MessageComposer/Util"
Laurent Montel's avatar
Laurent Montel committed
82

83
#include <kcontacts/vcardconverter.h>
Laurent Montel's avatar
Laurent Montel committed
84 85 86
#include "SendLater/SendLaterUtil"
#include "SendLater/SendLaterDialog"
#include "SendLater/SendLaterInfo"
Laurent Montel's avatar
Laurent Montel committed
87

Thomas McGuire's avatar
Thomas McGuire committed
88
// KDEPIM includes
Laurent Montel's avatar
Laurent Montel committed
89 90
#include <Libkleo/ProgressDialog>
#include <Libkleo/KeySelectionDialog>
Laurent Montel's avatar
Laurent Montel committed
91 92 93
#include <Libkleo/CryptoBackendFactory>
#include <Libkleo/ExportJob>
#include <Libkleo/SpecialJob>
Laurent Montel's avatar
Laurent Montel committed
94 95

#ifndef QT_NO_CURSOR
96
#include <Libkdepim/KCursorSaver>
Laurent Montel's avatar
Laurent Montel committed
97 98
#endif

99 100 101
#include <MessageViewer/MessageViewerSettings>
#include <MimeTreeParser/ObjectTreeParser>
#include <MimeTreeParser/NodeHelper>
Laurent Montel's avatar
Laurent Montel committed
102 103 104 105
#include <MessageComposer/Composer>
#include <MessageComposer/GlobalPart>
#include <MessageComposer/InfoPart>
#include <MessageComposer/TextPart>
Laurent Montel's avatar
Laurent Montel committed
106
#include <messagecomposer/messagecomposersettings.h>
Laurent Montel's avatar
Laurent Montel committed
107 108 109 110
#include <MessageComposer/MessageHelper>
#include <MessageComposer/SignatureController>
#include <MessageComposer/InsertTextFileJob>
#include <MessageComposer/ComposerLineEdit>
Laurent Montel's avatar
Laurent Montel committed
111
#include <MessageCore/AttachmentPart>
Laurent Montel's avatar
Laurent Montel committed
112
#include <MessageCore/MessageCoreSettings>
113
#include <templateparser.h>
114
#include <TemplateParser/TemplatesConfiguration>
Laurent Montel's avatar
Laurent Montel committed
115
#include <MessageCore/NodeHelper>
116
#include <Akonadi/KMime/MessageStatus>
Laurent Montel's avatar
Laurent Montel committed
117
#include "messagecore/messagehelpers.h"
Laurent Montel's avatar
Laurent Montel committed
118 119
#include <MailCommon/FolderRequester>
#include <MailCommon/FolderCollection>
Thomas McGuire's avatar
Thomas McGuire committed
120

Laurent Montel's avatar
Laurent Montel committed
121
#include "widgets/statusbarlabeltoggledstate.h"
122

Thomas McGuire's avatar
Thomas McGuire committed
123
// KDEPIMLIBS includes
Laurent Montel's avatar
Laurent Montel committed
124
#include <AkonadiCore/changerecorder.h>
Laurent Montel's avatar
Laurent Montel committed
125 126
#include <AkonadiCore/Monitor>
#include <AkonadiCore/ItemFetchJob>
Laurent Montel's avatar
Laurent Montel committed
127 128 129 130
#include <KIdentityManagement/kidentitymanagement/identitymanager.h>
#include <KIdentityManagement/kidentitymanagement/identitycombo.h>
#include <KIdentityManagement/kidentitymanagement/identity.h>
#include <KIdentityManagement/kidentitymanagement/signature.h>
Laurent Montel's avatar
Laurent Montel committed
131 132 133
#include <MailTransport/mailtransport/transportcombobox.h>
#include <MailTransport/mailtransport/transportmanager.h>
#include <MailTransport/mailtransport/transport.h>
134
#include <Akonadi/KMime/MessageFlags>
Laurent Montel's avatar
Laurent Montel committed
135
#include <kmime/kmime_message.h>
Laurent Montel's avatar
Laurent Montel committed
136
#include <kpimtextedit/selectspecialchardialog.h>
137

Thomas McGuire's avatar
Thomas McGuire committed
138 139 140
// KDELIBS includes
#include <kactioncollection.h>
#include <kactionmenu.h>
141
#include <kcharsets.h>
Laurent Montel's avatar
Laurent Montel committed
142
#include "kmail_debug.h"
143
#include <kdescendantsproxymodel.h>
144
#include <kedittoolbar.h>
Laurent Montel's avatar
Laurent Montel committed
145

146 147 148
#include <kmessagebox.h>
#include <krecentfilesaction.h>
#include <kshortcutsdialog.h>
Laurent Montel's avatar
Laurent Montel committed
149

150 151 152 153 154
#include <kstandardshortcut.h>
#include <ktoggleaction.h>
#include <ktoolbar.h>
#include <ktoolinvocation.h>
#include <sonnet/dictionarycombobox.h>
Laurent Montel's avatar
Laurent Montel committed
155
#include <krun.h>
Laurent Montel's avatar
Laurent Montel committed
156
#include <KIO/JobUiDelegate>
Laurent Montel's avatar
Laurent Montel committed
157
#include <QFileDialog>
158
#include <KEmailAddress>
159 160 161 162
#include <KEncodingFileDialog>
#include <KHelpClient>
#include <KCharsets>
#include <KConfigGroup>
Laurent Montel's avatar
Laurent Montel committed
163
#include <KXMLGUIFactory>
164 165

// Qt includes
166 167 168 169 170
#include <QMenu>
#include <qinputdialog.h>
#include <qstatusbar.h>
#include <QTemporaryDir>
#include <QAction>
171 172
#include <QClipboard>
#include <QSplitter>
Tobias Koenig's avatar
Tobias Koenig committed
173
#include <QMimeData>
174
#include <QTextDocumentWriter>
175
#include <QApplication>
176 177 178 179 180
#include <QCheckBox>
#include <QStandardPaths>
#include <QFontDatabase>
#include <QMimeDatabase>
#include <QMimeType>
181 182 183 184 185 186

// System includes
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <memory>
187
#include <KSplitterCollapserButton>
Laurent Montel's avatar
Laurent Montel committed
188
#include <Akonadi/Contact/ContactGroupExpandJob>
Laurent Montel's avatar
Laurent Montel committed
189
#include <editor/potentialphishingemail/potentialphishingemailjob.h>
190

Thomas McGuire's avatar
Thomas McGuire committed
191 192 193
using Sonnet::DictionaryComboBox;
using MailTransport::TransportManager;
using MailTransport::Transport;
194

Laurent Montel's avatar
Laurent Montel committed
195 196 197 198
KMail::Composer *KMail::makeComposer(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
199
    return KMComposerWin::create(msg, lastSignState, lastEncryptState, context, identity, textSelection, customTemplate);
200 201
}

Laurent Montel's avatar
Laurent Montel committed
202
KMail::Composer *KMComposerWin::create(const KMime::Message::Ptr &msg, bool lastSignState, bool lastEncryptState, Composer::TemplateContext context,
Laurent Montel's avatar
Laurent Montel committed
203 204
                                       uint identity, const QString &textSelection,
                                       const QString &customTemplate)
Laurent Montel's avatar
Laurent Montel committed
205
{
Laurent Montel's avatar
Laurent Montel committed
206
    return new KMComposerWin(msg, lastSignState, lastEncryptState, context, identity, textSelection, customTemplate);
207 208
}

Laurent Montel's avatar
Laurent Montel committed
209
int KMComposerWin::s_composerNumber = 0;
210

Laurent Montel's avatar
Laurent Montel committed
211
KMComposerWin::KMComposerWin(const KMime::Message::Ptr &aMsg, bool lastSignState, bool lastEncryptState, Composer::TemplateContext context, uint id,
Laurent Montel's avatar
Laurent Montel committed
212
                             const QString &textSelection, const QString &customTemplate)
Laurent Montel's avatar
Laurent Montel committed
213 214 215 216 217 218 219 220 221
    : KMail::Composer("kmail-composer#"),
      mDone(false),
      mTextSelection(textSelection),
      mCustomTemplate(customTemplate),
      mSigningAndEncryptionExplicitlyDisabled(false),
      mFolder(Akonadi::Collection(-1)),
      mForceDisableHtml(false),
      mId(id),
      mContext(context),
Laurent Montel's avatar
Laurent Montel committed
222 223 224 225 226
      mSignAction(Q_NULLPTR), mEncryptAction(Q_NULLPTR), mRequestMDNAction(Q_NULLPTR),
      mUrgentAction(Q_NULLPTR), mAllFieldsAction(Q_NULLPTR), mFromAction(Q_NULLPTR),
      mReplyToAction(Q_NULLPTR), mSubjectAction(Q_NULLPTR),
      mIdentityAction(Q_NULLPTR), mTransportAction(Q_NULLPTR), mFccAction(Q_NULLPTR),
      mWordWrapAction(Q_NULLPTR), mFixedFontAction(Q_NULLPTR), mAutoSpellCheckingAction(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
227
      mDictionaryAction(Q_NULLPTR), mSnippetAction(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
228 229 230 231 232 233 234 235
      mAppendSignature(Q_NULLPTR), mPrependSignature(Q_NULLPTR), mInsertSignatureAtCursorPosition(Q_NULLPTR),
      mCodecAction(Q_NULLPTR),
      mCryptoModuleAction(Q_NULLPTR),
      mFindText(Q_NULLPTR),
      mFindNextText(Q_NULLPTR),
      mReplaceText(Q_NULLPTR),
      mSelectAll(Q_NULLPTR),
      mDummyComposer(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
236
      mLabelWidth(0),
Laurent Montel's avatar
Laurent Montel committed
237 238
      mComposerBase(Q_NULLPTR),
      m_verifyMissingAttachment(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
239 240 241
      mPreventFccOverwrite(false),
      mCheckForForgottenAttachments(true),
      mWasModified(false),
Laurent Montel's avatar
Laurent Montel committed
242
      mCryptoStateIndicatorWidget(Q_NULLPTR),
243
      mSendNowByShortcutUsed(false),
Laurent Montel's avatar
Laurent Montel committed
244 245
      mFollowUpToggleAction(Q_NULLPTR),
      mStatusBarLabelToggledOverrideMode(Q_NULLPTR),
246
      mStatusBarLabelSpellCheckingChangeMode(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
247
      mPluginEditorManagerInterface(Q_NULLPTR)
Laurent Montel's avatar
Laurent Montel committed
248
{
Laurent Montel's avatar
Laurent Montel committed
249
    mGlobalAction = new KMComposerGlobalAction(this, this);
Laurent Montel's avatar
Laurent Montel committed
250 251
    mComposerBase = new MessageComposer::ComposerViewBase(this, this);
    mComposerBase->setIdentityManager(kmkernel->identityManager());
Laurent Montel's avatar
Laurent Montel committed
252

Laurent Montel's avatar
Laurent Montel committed
253 254
    mPluginEditorManagerInterface = new KMailPluginEditorManagerInterface(this);

Laurent Montel's avatar
Laurent Montel committed
255 256 257 258 259
    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
260

Laurent Montel's avatar
Laurent Montel committed
261 262 263
    (void) new MailcomposerAdaptor(this);
    mdbusObjectPath = QLatin1String("/Composer_") + QString::number(++s_composerNumber);
    QDBusConnection::sessionBus().registerObject(mdbusObjectPath, this);
Laurent Montel's avatar
Laurent Montel committed
264

Laurent Montel's avatar
Laurent Montel committed
265
    MessageComposer::SignatureController *sigController = new MessageComposer::SignatureController(this);
Laurent Montel's avatar
Laurent Montel committed
266
    connect(sigController, &MessageComposer::SignatureController::enableHtml, this, &KMComposerWin::enableHtml);
Laurent Montel's avatar
Laurent Montel committed
267
    mComposerBase->setSignatureController(sigController);
Laurent Montel's avatar
Laurent Montel committed
268

Laurent Montel's avatar
Laurent Montel committed
269
    if (!kmkernel->xmlGuiInstanceName().isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
270
        setComponentName(kmkernel->xmlGuiInstanceName(), i18n("KMail2"));
Laurent Montel's avatar
Laurent Montel committed
271
    }
Laurent Montel's avatar
Laurent Montel committed
272
    mMainWidget = new QWidget(this);
Laurent Montel's avatar
Laurent Montel committed
273
    // splitter between the headers area and the actual editor
Laurent Montel's avatar
Laurent Montel committed
274
    mHeadersToEditorSplitter = new QSplitter(Qt::Vertical, mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
275
    mHeadersToEditorSplitter->setObjectName(QStringLiteral("mHeadersToEditorSplitter"));
Laurent Montel's avatar
Laurent Montel committed
276 277 278 279 280
    mHeadersToEditorSplitter->setChildrenCollapsible(false);
    mHeadersArea = new QWidget(mHeadersToEditorSplitter);
    mHeadersArea->setSizePolicy(mHeadersToEditorSplitter->sizePolicy().horizontalPolicy(),
                                QSizePolicy::Expanding);
    mHeadersToEditorSplitter->addWidget(mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
281 282
    QList<int> defaultSizes;
    defaultSizes << 0;
Laurent Montel's avatar
Laurent Montel committed
283
    mHeadersToEditorSplitter->setSizes(defaultSizes);
Laurent Montel's avatar
Laurent Montel committed
284

Laurent Montel's avatar
Laurent Montel committed
285
    QVBoxLayout *v = new QVBoxLayout(mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
286
    v->setMargin(0);
Laurent Montel's avatar
Laurent Montel committed
287 288 289 290
    v->addWidget(mHeadersToEditorSplitter);
    KIdentityManagement::IdentityCombo *identity = new KIdentityManagement::IdentityCombo(kmkernel->identityManager(),
            mHeadersArea);
    identity->setToolTip(i18n("Select an identity for this message"));
291
    identity->setCurrentIdentity(mId);
Laurent Montel's avatar
Laurent Montel committed
292
    mComposerBase->setIdentityCombo(identity);
Laurent Montel's avatar
Laurent Montel committed
293

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

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

Laurent Montel's avatar
Laurent Montel committed
301 302 303
    mFccFolder = new MailCommon::FolderRequester(mHeadersArea);
    mFccFolder->setNotAllowToCreateNewFolder(true);
    mFccFolder->setMustBeReadWrite(true);
Laurent Montel's avatar
Laurent Montel committed
304

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

Laurent Montel's avatar
Laurent Montel committed
308 309 310
    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
311
    connect(transport, static_cast<void (MailTransport::TransportComboBox::*)(int)>(&MailTransport::TransportComboBox::activated), this, &KMComposerWin::slotTransportChanged);
Laurent Montel's avatar
Laurent Montel committed
312

Laurent Montel's avatar
Laurent Montel committed
313
    mEdtFrom = new MessageComposer::ComposerLineEdit(false, mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
314
    mEdtFrom->setObjectName(QStringLiteral("fromLine"));
Laurent Montel's avatar
Laurent Montel committed
315 316 317
    mEdtFrom->setRecentAddressConfig(MessageComposer::MessageComposerSettings::self()->config());
    mEdtFrom->setToolTip(i18n("Set the \"From:\" email address for this message"));
    mEdtReplyTo = new MessageComposer::ComposerLineEdit(true, mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
318
    mEdtReplyTo->setObjectName(QStringLiteral("replyToLine"));
Laurent Montel's avatar
Laurent Montel committed
319 320
    mEdtReplyTo->setRecentAddressConfig(MessageComposer::MessageComposerSettings::self()->config());
    mEdtReplyTo->setToolTip(i18n("Set the \"Reply-To:\" email address for this message"));
Laurent Montel's avatar
Laurent Montel committed
321
    connect(mEdtReplyTo, &MessageComposer::ComposerLineEdit::completionModeChanged, this, &KMComposerWin::slotCompletionModeChanged);
Laurent Montel's avatar
Laurent Montel committed
322

Laurent Montel's avatar
Laurent Montel committed
323 324
    MessageComposer::RecipientsEditor *recipientsEditor = new MessageComposer::RecipientsEditor(mHeadersArea);
    recipientsEditor->setRecentAddressConfig(MessageComposer::MessageComposerSettings::self()->config());
Laurent Montel's avatar
Laurent Montel committed
325 326
    connect(recipientsEditor, &MessageComposer::RecipientsEditor::completionModeChanged, this, &KMComposerWin::slotCompletionModeChanged);
    connect(recipientsEditor, &MessageComposer::RecipientsEditor::sizeHintChanged, this, &KMComposerWin::recipientEditorSizeHintChanged);
Laurent Montel's avatar
Laurent Montel committed
327
    mComposerBase->setRecipientsEditor(recipientsEditor);
Laurent Montel's avatar
Laurent Montel committed
328

Laurent Montel's avatar
Laurent Montel committed
329
    mEdtSubject = new PimCommon::LineEditWithAutoCorrection(mHeadersArea, QStringLiteral("kmail2rc"));
Laurent Montel's avatar
Laurent Montel committed
330
    mEdtSubject->setActivateLanguageMenu(false);
Laurent Montel's avatar
Laurent Montel committed
331
    mEdtSubject->setToolTip(i18n("Set a subject for this message"));
Laurent Montel's avatar
Laurent Montel committed
332
    mEdtSubject->setAutocorrection(KMKernel::self()->composerAutoCorrection());
Laurent Montel's avatar
Laurent Montel committed
333 334 335 336 337 338 339
    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);
    mLblReplyTo = new QLabel(i18n("&Reply to:"), mHeadersArea);
    mLblSubject = new QLabel(i18nc("@label:textbox Subject of email.", "S&ubject:"), mHeadersArea);
Laurent Montel's avatar
Laurent Montel committed
340
    mShowHeaders = KMailSettings::self()->headers();
Laurent Montel's avatar
Laurent Montel committed
341
    mDone = false;
Laurent Montel's avatar
Laurent Montel committed
342 343
    mGrid = Q_NULLPTR;
    mFixedFontAction = Q_NULLPTR;
Laurent Montel's avatar
Laurent Montel committed
344
    // the attachment view is separated from the editor by a splitter
Laurent Montel's avatar
Laurent Montel committed
345
    mSplitter = new QSplitter(Qt::Vertical, mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
346
    mSplitter->setObjectName(QStringLiteral("mSplitter"));
Laurent Montel's avatar
Laurent Montel committed
347 348
    mSplitter->setChildrenCollapsible(false);
    mSnippetSplitter = new QSplitter(Qt::Horizontal, mSplitter);
Laurent Montel's avatar
Laurent Montel committed
349
    mSnippetSplitter->setObjectName(QStringLiteral("mSnippetSplitter"));
Laurent Montel's avatar
Laurent Montel committed
350 351 352
    mSplitter->addWidget(mSnippetSplitter);

    QWidget *editorAndCryptoStateIndicators = new QWidget(mSplitter);
353
    mCryptoStateIndicatorWidget = new CryptoStateIndicatorWidget;
Laurent Montel's avatar
Laurent Montel committed
354
    mCryptoStateIndicatorWidget->setShowAlwaysIndicator(KMailSettings::self()->showCryptoLabelIndicator());
Laurent Montel's avatar
Laurent Montel committed
355

356 357
    QVBoxLayout *vbox = new QVBoxLayout(editorAndCryptoStateIndicators);
    vbox->setMargin(0);
358

359
    KMComposerEditorNg *editor = new KMComposerEditorNg(this, mCryptoStateIndicatorWidget);
Laurent Montel's avatar
Laurent Montel committed
360
    mRichTextEditorwidget = new KPIMTextEdit::RichTextEditorWidget(editor, mCryptoStateIndicatorWidget);
Laurent Montel's avatar
Laurent Montel committed
361

362
    //Don't use new connect api here. It crashs
363
    connect(editor, SIGNAL(textChanged()), this, SLOT(slotEditorTextChanged()));
364
    //connect(editor, &KMComposerEditor::textChanged, this, &KMComposeWin::slotEditorTextChanged);
Laurent Montel's avatar
Laurent Montel committed
365 366
    mComposerBase->setEditor(editor);
    vbox->addWidget(mCryptoStateIndicatorWidget);
367
    vbox->addWidget(mRichTextEditorwidget);
Laurent Montel's avatar
Laurent Montel committed
368

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

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

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

Laurent Montel's avatar
Laurent Montel committed
380 381 382 383
    connect(editor, &KMComposerEditorNg::languageChanged, this, &KMComposerWin::slotLanguageChanged);
    connect(editor, &KMComposerEditorNg::spellCheckStatus, this, &KMComposerWin::slotSpellCheckingStatus);
    connect(editor, &KMComposerEditorNg::insertModeChanged, this, &KMComposerWin::slotOverwriteModeChanged);
    connect(editor, &KMComposerEditorNg::spellCheckingFinished, this, &KMComposerWin::slotCheckSendNow);
Laurent Montel's avatar
Laurent Montel committed
384
    mSnippetWidget = new SnippetWidget(editor, actionCollection(), mSnippetSplitter);
Laurent Montel's avatar
Laurent Montel committed
385
    mSnippetWidget->setVisible(KMailSettings::self()->showSnippetManager());
Laurent Montel's avatar
Laurent Montel committed
386 387
    mSnippetSplitter->addWidget(mSnippetWidget);
    mSnippetSplitter->setCollapsible(0, false);
388
    mSnippetSplitterCollapser = new KSplitterCollapserButton(mSnippetWidget, mSnippetSplitter);
Laurent Montel's avatar
Laurent Montel committed
389
    mSnippetSplitterCollapser->setVisible(KMailSettings::self()->showSnippetManager());
Laurent Montel's avatar
Laurent Montel committed
390

Laurent Montel's avatar
Laurent Montel committed
391
    mSplitter->setOpaqueResize(true);
Laurent Montel's avatar
Laurent Montel committed
392

Laurent Montel's avatar
Laurent Montel committed
393 394
    setWindowTitle(i18n("Composer"));
    setMinimumSize(200, 200);
Laurent Montel's avatar
Laurent Montel committed
395

Laurent Montel's avatar
Laurent Montel committed
396
    mCustomToolsWidget = new PimCommon::CustomToolsWidgetNg(actionCollection(), this);
Laurent Montel's avatar
Laurent Montel committed
397
    mSplitter->addWidget(mCustomToolsWidget);
Laurent Montel's avatar
Laurent Montel committed
398
    connect(mCustomToolsWidget, &PimCommon::CustomToolsWidgetNg::insertText, this, &KMComposerWin::slotInsertShortUrl);
Laurent Montel's avatar
Laurent Montel committed
399

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

Laurent Montel's avatar
Laurent Montel committed
406 407
    mComposerBase->setAttachmentModel(attachmentModel);
    mComposerBase->setAttachmentController(attachmentController);
Laurent Montel's avatar
Laurent Montel committed
408 409

    mAttachmentMissing = new AttachmentMissingWarning(this);
Laurent Montel's avatar
Laurent Montel committed
410 411
    connect(mAttachmentMissing, &AttachmentMissingWarning::attachMissingFile, this, &KMComposerWin::slotAttachMissingFile);
    connect(mAttachmentMissing, &AttachmentMissingWarning::explicitClosedMissingAttachment, this, &KMComposerWin::slotExplicitClosedMissingAttachment);
Laurent Montel's avatar
Laurent Montel committed
412 413
    v->addWidget(mAttachmentMissing);

Laurent Montel's avatar
Laurent Montel committed
414
    mPotentialPhishingEmailWarning = new PotentialPhishingEmailWarning(this);
Laurent Montel's avatar
Laurent Montel committed
415
    connect(mPotentialPhishingEmailWarning, &PotentialPhishingEmailWarning::sendNow, this, &KMComposerWin::slotCheckSendNowStep2);
Laurent Montel's avatar
Laurent Montel committed
416 417
    v->addWidget(mPotentialPhishingEmailWarning);

Laurent Montel's avatar
Laurent Montel committed
418
    if (KMailSettings::self()->showForgottenAttachmentWarning()) {
419
        m_verifyMissingAttachment = new QTimer(this);
420
        m_verifyMissingAttachment->setSingleShot(true);
Laurent Montel's avatar
Laurent Montel committed
421
        m_verifyMissingAttachment->setInterval(1000 * 5);
Laurent Montel's avatar
Laurent Montel committed
422
        connect(m_verifyMissingAttachment, &QTimer::timeout, this, &KMComposerWin::slotVerifyMissingAttachmentTimeout);
423
    }
Laurent Montel's avatar
Laurent Montel committed
424
    connect(attachmentController, &KMail::AttachmentController::fileAttached, mAttachmentMissing, &AttachmentMissingWarning::slotFileAttached);
Laurent Montel's avatar
Laurent Montel committed
425 426 427 428

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

Laurent Montel's avatar
Laurent Montel committed
429 430
    mPluginEditorManagerInterface->setParentWidget(this);
    mPluginEditorManagerInterface->setRichTextEditor(mRichTextEditorwidget->editor());
Laurent Montel's avatar
Laurent Montel committed
431
    mPluginEditorManagerInterface->setActionCollection(actionCollection());
Laurent Montel's avatar
Laurent Montel committed
432

Laurent Montel's avatar
Laurent Montel committed
433 434 435 436
    setupStatusBar(attachmentView->widget());
    setupActions();
    setupEditor();
    rethinkFields();
437 438
    readConfig();

Laurent Montel's avatar
Laurent Montel committed
439
    updateSignatureAndEncryptionStateIndicators();
Laurent Montel's avatar
Laurent Montel committed
440

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

Laurent Montel's avatar
Laurent Montel committed
443
    connect(mEdtSubject, &PimCommon::LineEditWithAutoCorrection::textChanged, this, &KMComposerWin::slotUpdateWindowTitle);
Laurent Montel's avatar
Laurent Montel committed
444 445 446 447
    connect(identity, SIGNAL(identityChanged(uint)),
            SLOT(slotIdentityChanged(uint)));
    connect(kmkernel->identityManager(), SIGNAL(changed(uint)),
            SLOT(slotIdentityChanged(uint)));
Laurent Montel's avatar
Laurent Montel committed
448

Laurent Montel's avatar
Laurent Montel committed
449 450 451
    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
452

Laurent Montel's avatar
Laurent Montel committed
453
    mMainWidget->resize(800, 600);
Laurent Montel's avatar
Laurent Montel committed
454
    setCentralWidget(mMainWidget);
Laurent Montel's avatar
Laurent Montel committed
455

Laurent Montel's avatar
Laurent Montel committed
456
    if (KMailSettings::self()->useHtmlMarkup()) {
Laurent Montel's avatar
Laurent Montel committed
457
        enableHtml();
Laurent Montel's avatar
Laurent Montel committed
458 459 460
    } else {
        disableHtml(MessageComposer::ComposerViewBase::LetUserConfirm);
    }
Laurent Montel's avatar
Laurent Montel committed
461

Laurent Montel's avatar
Laurent Montel committed
462
    if (KMailSettings::self()->useExternalEditor()) {
Laurent Montel's avatar
Laurent Montel committed
463
        editor->setUseExternalEditor(true);
Laurent Montel's avatar
Laurent Montel committed
464
        editor->setExternalEditorPath(KMailSettings::self()->externalEditor());
Laurent Montel's avatar
Laurent Montel committed
465 466
    }

Laurent Montel's avatar
Laurent Montel committed
467 468
    if (aMsg) {
        setMessage(aMsg, lastSignState, lastEncryptState);
Laurent Montel's avatar
Laurent Montel committed
469 470 471
    }

    mComposerBase->recipientsEditor()->setFocus();
472
    editor->composerActions()->updateActionStates(); // set toolbar buttons to correct values
Laurent Montel's avatar
Laurent Montel committed
473 474 475

    mDone = true;

Laurent Montel's avatar
Laurent Montel committed
476 477
    mDummyComposer = new MessageComposer::Composer(this);
    mDummyComposer->globalPart()->setParentWidgetForGui(this);
478 479
}

Laurent Montel's avatar
Laurent Montel committed
480
KMComposerWin::~KMComposerWin()
481
{
Laurent Montel's avatar
Laurent Montel committed
482 483 484 485 486
    writeConfig();

    // 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
487
    if (mFolder.isValid() && mMsg && isModified()) {
488 489
        SaveDraftJob *saveDraftJob = new SaveDraftJob(mMsg, mFolder);
        saveDraftJob->start();
Laurent Montel's avatar
Laurent Montel committed
490
    }
491

Laurent Montel's avatar
Laurent Montel committed
492
    delete mComposerBase;
493 494
}

Laurent Montel's avatar
Laurent Montel committed
495
void KMComposerWin::slotSpellCheckingLanguage(const QString &language)
Laurent Montel's avatar
Laurent Montel committed
496
{
Laurent Montel's avatar
Laurent Montel committed
497 498
    mComposerBase->editor()->setSpellCheckingLanguage(language);
    mEdtSubject->setSpellCheckingLanguage(language);
Laurent Montel's avatar
Laurent Montel committed
499 500
}

Laurent Montel's avatar
Laurent Montel committed
501
QString KMComposerWin::dbusObjectPath() const
502
{
Laurent Montel's avatar
Laurent Montel committed
503
    return mdbusObjectPath;
504 505
}

Laurent Montel's avatar
Laurent Montel committed
506
void KMComposerWin::slotEditorTextChanged()
Allen Winter's avatar
Allen Winter committed
507
{
Laurent Montel's avatar
Laurent Montel committed
508
    const bool textIsNotEmpty = !mComposerBase->editor()->document()->isEmpty();
Laurent Montel's avatar
Laurent Montel committed
509 510 511 512
    mFindText->setEnabled(textIsNotEmpty);
    mFindNextText->setEnabled(textIsNotEmpty);
    mReplaceText->setEnabled(textIsNotEmpty);
    mSelectAll->setEnabled(textIsNotEmpty);
513 514 515
    if (m_verifyMissingAttachment && !m_verifyMissingAttachment->isActive()) {
        m_verifyMissingAttachment->start();
    }
Allen Winter's avatar
Allen Winter committed
516 517
}

Laurent Montel's avatar
Laurent Montel committed
518
void KMComposerWin::send(int how)
519
{
Laurent Montel's avatar
Laurent Montel committed
520
    switch (how) {
Laurent Montel's avatar
Laurent Montel committed
521 522 523 524 525
    case 1:
        slotSendNow();
        break;
    default:
    case 0:
Laurent Montel's avatar
Laurent Montel committed
526
    // TODO: find out, what the default send method is and send it this way
Laurent Montel's avatar
Laurent Montel committed
527 528 529 530
    case 2:
        slotSendLater();
        break;
    }
531 532
}

Laurent Montel's avatar
Laurent Montel committed
533
void KMComposerWin::addAttachmentsAndSend(const QList<QUrl> &urls, const QString &comment, int how)
534
{
Laurent Montel's avatar
Laurent Montel committed
535
    const int nbUrl = urls.count();
Laurent Montel's avatar
Laurent Montel committed
536
    for (int i = 0; i < nbUrl; ++i) {
537
        mComposerBase->addAttachment(urls.at(i), comment, true);
Laurent Montel's avatar
Laurent Montel committed
538
    }
Laurent Montel's avatar
Laurent Montel committed
539

Laurent Montel's avatar
Laurent Montel committed
540
    send(how);
541 542
}

Laurent Montel's avatar
Laurent Montel committed
543
void KMComposerWin::addAttachment(const QUrl &url, const QString &comment)
544
{
545
    mComposerBase->addAttachment(url, comment, false);
546 547
}

Laurent Montel's avatar
Laurent Montel committed
548
void KMComposerWin::addAttachment(const QString &name,
Laurent Montel's avatar
Laurent Montel committed
549 550 551 552
                                  KMime::Headers::contentEncoding cte,
                                  const QString &charset,
                                  const QByteArray &data,
                                  const QByteArray &mimeType)
553
{
Laurent Montel's avatar
Laurent Montel committed
554 555
    Q_UNUSED(cte);
    mComposerBase->addAttachment(name, name, charset, data, mimeType);
556 557
}

Laurent Montel's avatar
Laurent Montel committed
558
void KMComposerWin::readConfig(bool reload /* = false */)
559
{
Laurent Montel's avatar
Laurent Montel committed
560 561 562
    mEdtFrom->setCompletionMode((KCompletion::CompletionMode)KMailSettings::self()->completionMode());
    mComposerBase->recipientsEditor()->setCompletionMode((KCompletion::CompletionMode)KMailSettings::self()->completionMode());
    mEdtReplyTo->setCompletionMode((KCompletion::CompletionMode)KMailSettings::self()->completionMode());
Laurent Montel's avatar
Laurent Montel committed
563

Laurent Montel's avatar
Laurent Montel committed
564
    if (MessageCore::MessageCoreSettings::self()->useDefaultFonts()) {
Laurent Montel's avatar
Laurent Montel committed
565 566
        mBodyFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
        mFixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
567
    } else {
Laurent Montel's avatar
Laurent Montel committed
568
        mBodyFont = KMailSettings::self()->composerFont();
Laurent Montel's avatar
Laurent Montel committed
569
        mFixedFont = MessageViewer::MessageViewerSettings::self()->fixedFont();
570 571
    }

Laurent Montel's avatar
Laurent Montel committed
572
    slotUpdateFont();
Laurent Montel's avatar
Laurent Montel committed
573 574 575
    mEdtFrom->setFont(mBodyFont);
    mEdtReplyTo->setFont(mBodyFont);
    mEdtSubject->setFont(mBodyFont);
576

Laurent Montel's avatar
Laurent Montel committed
577
    if (!reload) {
Laurent Montel's avatar
Laurent Montel committed
578
        QSize siz = KMailSettings::self()->composerSize();
Laurent Montel's avatar
Laurent Montel committed
579 580
        if (siz.width() < 200) {
            siz.setWidth(200);
Laurent Montel's avatar
Laurent Montel committed
581
        }
Laurent Montel's avatar
Laurent Montel committed
582 583
        if (siz.height() < 200) {
            siz.setHeight(200);
Laurent Montel's avatar
Laurent Montel committed
584
        }
Laurent Montel's avatar
Laurent Montel committed
585
        resize(siz);
Laurent Montel's avatar
Laurent Montel committed
586

Laurent Montel's avatar
Laurent Montel committed
587 588
        if (!KMailSettings::self()->snippetSplitterPosition().isEmpty()) {
            mSnippetSplitter->setSizes(KMailSettings::self()->snippetSplitterPosition());
Laurent Montel's avatar
Laurent Montel committed
589 590 591
        } else {
            QList<int> defaults;
            defaults << (int)(width() * 0.8) << (int)(width() * 0.2);
Laurent Montel's avatar
Laurent Montel committed
592
            mSnippetSplitter->setSizes(defaults);
Laurent Montel's avatar
Laurent Montel committed
593 594 595
        }
    }

Laurent Montel's avatar
Laurent Montel committed
596
    mComposerBase->identityCombo()->setCurrentIdentity(mId);
Laurent Montel's avatar
Laurent Montel committed
597
    qCDebug(KMAIL_LOG) << mComposerBase->identityCombo()->currentIdentityName();
Laurent Montel's avatar
Laurent Montel committed
598 599
    const KIdentityManagement::Identity &ident =
        kmkernel->identityManager()->identityForUoid(mId);
600

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

Laurent Montel's avatar
Laurent Montel committed
603
    mComposerBase->dictionary()->setCurrentByDictionaryName(ident.dictionary());
Laurent Montel's avatar
Laurent Montel committed
604 605

    QString fccName;
Laurent Montel's avatar
Laurent Montel committed
606
    if (!ident.fcc().isEmpty()) {
607
        fccName = ident.fcc();
Laurent Montel's avatar
Laurent Montel committed
608
    }
Laurent Montel's avatar
Laurent Montel committed
609
    setFcc(fccName);
610 611
}

Laurent Montel's avatar
Laurent Montel committed
612
void KMComposerWin::writeConfig(void)
Laurent Montel's avatar
Laurent Montel committed
613
{
Laurent Montel's avatar
Laurent Montel committed
614
    KMailSettings::self()->setHeaders(mShowHeaders);
Laurent Montel's avatar
Laurent Montel committed
615 616
    KMailSettings::self()->setCurrentTransport(mComposerBase->transportComboBox()->currentText());
    KMailSettings::self()->setPreviousIdentity(mComposerBase->identityCombo()->currentIdentity());
Laurent Montel's avatar
Laurent Montel committed
617 618
    KMailSettings::self()->setPreviousFcc(QString::number(mFccFolder->collection().id()));
    KMailSettings::self()->setPreviousDictionary(mComposerBase->dictionary()->currentDictionaryName());
Laurent Montel's avatar
Laurent Montel committed
619
    KMailSettings::self()->setAutoSpellChecking(mAutoSpellCheckingAction->isChecked());
Laurent Montel's avatar
Laurent Montel committed
620
    MessageViewer::MessageViewerSettings::self()->setUseFixedFont(mFixedFontAction->isChecked());
Laurent Montel's avatar
Laurent Montel committed
621
    if (!mForceDisableHtml) {
Laurent Montel's avatar
Laurent Montel committed
622
        KMailSettings::self()->setUseHtmlMarkup(mComposerBase->editor()->textMode() == MessageComposer::RichTextComposerNg::Rich);
Laurent Montel's avatar
Laurent Montel committed
623
    }
Laurent Montel's avatar
Laurent Montel committed
624 625
    KMailSettings::self()->setComposerSize(size());
    KMailSettings::self()->setShowSnippetManager(mSnippetAction->isChecked());
Laurent Montel's avatar
Laurent Montel committed
626 627 628 629

    KConfigGroup grp(KMKernel::self()->config()->group("Composer"));
    saveMainWindowSettings(grp);
    if (mSnippetAction->isChecked()) {
Laurent Montel's avatar
Laurent Montel committed
630
        KMailSettings::setSnippetSplitterPosition(mSnippetSplitter->sizes());
Laurent Montel's avatar
Laurent Montel committed
631
    }
Laurent Montel's avatar
Laurent Montel committed
632 633 634

    // make sure config changes are written to disk, cf. bug 127538
    KMKernel::self()->slotSyncConfig();
635 636
}

Laurent Montel's avatar
Laurent Montel committed
637
MessageComposer::Composer *KMComposerWin::createSimpleComposer()
638
{
Laurent Montel's avatar
Laurent Montel committed
639
    QList< QByteArray > charsets = mCodecAction->mimeCharsets();
Laurent Montel's avatar
Laurent Montel committed
640 641
    if (!mOriginalPreferredCharset.isEmpty()) {
        charsets.insert(0, mOriginalPreferredCharset);
Laurent Montel's avatar
Laurent Montel committed
642
    }
Laurent Montel's avatar
Laurent Montel committed
643 644 645 646
    mComposerBase->setFrom(from());
    mComposerBase->setReplyTo(replyTo());
    mComposerBase->setSubject(subject());
    mComposerBase->setCharsets(charsets);
Laurent Montel's avatar
Laurent Montel committed
647
    return mComposerBase->createSimpleComposer();
648 649
}

Laurent Montel's avatar
Laurent Montel committed
650
bool KMComposerWin::canSignEncryptAttachments() const
Laurent Montel's avatar
Laurent Montel committed
651 652 653 654
{
    return cryptoMessageFormat() != Kleo::InlineOpenPGPFormat;
}

Laurent Montel's avatar
Laurent Montel committed
655
void KMComposerWin::slotUpdateView(void)
656
{
Laurent Montel's avatar
Laurent Montel committed
657
    if (!mDone) {
Laurent Montel's avatar
Laurent Montel committed
658 659 660 661 662 663
        return; // otherwise called from rethinkFields during the construction
        // which is not the intended behavior
    }

    //This sucks awfully, but no, I cannot get an activated(int id) from
    // actionContainer()
Laurent Montel's avatar
Laurent Montel committed
664 665
    KToggleAction *act = ::qobject_cast<KToggleAction *>(sender());
    if (!act) {
Laurent Montel's avatar
Laurent Montel committed
666 667 668 669
        return;
    }
    int id;

Laurent Montel's avatar
Laurent Montel committed
670
    if (act == mAllFieldsAction) {
Laurent Montel's avatar
Laurent Montel committed
671
        id = 0;
Laurent Montel's avatar
Laurent Montel committed
672
    } else if (act == mIdentityAction) {
Laurent Montel's avatar
Laurent Montel committed
673
        id = HDR_IDENTITY;
Laurent Montel's avatar
Laurent Montel committed
674
    } else if (act == mTransportAction) {
Laurent Montel's avatar
Laurent Montel committed
675
        id = HDR_TRANSPORT;
Laurent Montel's avatar
Laurent Montel committed
676
    } else if (act == mFromAction) {
Laurent Montel's avatar
Laurent Montel committed
677
        id = HDR_FROM;
Laurent Montel's avatar
Laurent Montel committed
678
    } else if (act == mReplyToAction) {
Laurent Montel's avatar
Laurent Montel committed
679
        id = HDR_REPLY_TO;
Laurent Montel's avatar
Laurent Montel committed
680
    } else if (act == mSubjectAction) {
Laurent Montel's avatar
Laurent Montel committed
681
        id = HDR_SUBJECT;
Laurent Montel's avatar
Laurent Montel committed
682
    } else if (act == mFccAction) {
Laurent Montel's avatar
Laurent Montel committed
683
        id = HDR_FCC;
Laurent Montel's avatar
Laurent Montel committed
684
    } else if (act == mDictionaryAction) {
Laurent Montel's avatar
Laurent Montel committed
685
        id = HDR_DICTIONARY;
686
    } else {
Laurent Montel's avatar
Laurent Montel committed
687
        qCDebug(KMAIL_LOG) << "Something is wrong (Oh, yeah?)";
Laurent Montel's avatar
Laurent Montel committed
688
        return;
689
    }
Laurent Montel's avatar
Laurent Montel committed
690 691 692 693

    // sanders There's a bug here this logic doesn't work if no
    // fields are shown and then show all fields is selected.
    // Instead of all fields being shown none are.
Laurent Montel's avatar
Laurent Montel committed
694
    if (!act->isChecked()) {
Laurent Montel's avatar
Laurent Montel committed
695
        // hide header
Laurent Montel's avatar
Laurent Montel committed
696
        if (id > 0) {
Laurent Montel's avatar
Laurent Montel committed
697 698
            mShowHeaders = mShowHeaders & ~id;
        } else {
699
            mShowHeaders = std::abs(mShowHeaders);
Laurent Montel's avatar
Laurent Montel committed
700
        }
701
    } else {
Laurent Montel's avatar
Laurent Montel committed
702
        // show header
Laurent Montel's avatar
Laurent Montel committed
703
        if (id > 0) {
Laurent Montel's avatar
Laurent Montel committed
704 705
            mShowHeaders |= id;
        } else {
706
            mShowHeaders = -std::abs(mShowHeaders);
Laurent Montel's avatar
Laurent Montel committed
707
        }
708
    }
Laurent Montel's avatar
Laurent Montel committed
709
    rethinkFields(true);
710 711
}

Laurent Montel's avatar
Laurent Montel committed
712
int KMComposerWin::calcColumnWidth(int which, long allShowing, int width) const
713
{
Laurent Montel's avatar
Laurent Montel committed
714
    if ((allShowing & which) == 0) {
Laurent Montel's avatar
Laurent Montel committed
715 716 717 718
        return width;
    }

    QLabel *w;
Laurent Montel's avatar
Laurent Montel committed
719
    if (which == HDR_IDENTITY) {
Laurent Montel's avatar
Laurent Montel committed
720
        w = mLblIdentity;
Laurent Montel's avatar
Laurent Montel committed
721
    } else if (which == HDR_DICTIONARY) {
Laurent Montel's avatar
Laurent Montel committed
722
        w = mDictionaryLabel;
Laurent Montel's avatar
Laurent Montel committed
723
    } else if (which == HDR_FCC) {
Laurent Montel's avatar
Laurent Montel committed
724
        w = mLblFcc;
Laurent Montel's avatar
Laurent Montel committed
725
    } else if (which == HDR_TRANSPORT) {
Laurent Montel's avatar
Laurent Montel committed
726
        w = mLblTransport;
Laurent Montel's avatar
Laurent Montel committed
727
    } else if (which == HDR_FROM) {
Laurent Montel's avatar
Laurent Montel committed
728
        w = mLblFrom;
Laurent Montel's avatar
Laurent Montel committed
729
    } else if (which == HDR_REPLY_TO) {
Laurent Montel's avatar
Laurent Montel committed