kmmainwidget.cpp 190 KB
Newer Older
<
Laurent Montel's avatar
Laurent Montel committed
1
/*
2 3
  This file is part of KMail, the KDE mail client.
  Copyright (c) 2002 Don Sanders <sanders@kde.org>
Laurent Montel's avatar
Laurent Montel committed
4
  Copyright (c) 2009-2016 Montel Laurent <montel@kde.org>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

  Based on the work of Stefan Taferner <taferner@kde.org>

  KMail is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License, version 2, as
  published by the Free Software Foundation.

  KMail 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
*/
Stephan Kulow's avatar
Stephan Kulow committed
21

Thomas McGuire's avatar
Thomas McGuire committed
22
// KMail includes
Leo Franchi's avatar
Leo Franchi committed
23
#include "kmreadermainwin.h"
Laurent Montel's avatar
Laurent Montel committed
24
#include "editor/composer.h"
Laurent Montel's avatar
Laurent Montel committed
25
#include "searchdialog/searchwindow.h"
26
#include "widgets/vacationscriptindicatorwidget.h"
Thomas McGuire's avatar
Thomas McGuire committed
27 28 29 30
#include "undostack.h"
#include "kmcommands.h"
#include "kmmainwin.h"
#include "kmsystemtray.h"
31
#include <TemplateParser/CustomTemplatesMenu>
Laurent Montel's avatar
Laurent Montel committed
32 33
#include "MailCommon/FolderSelectionDialog"
#include "MailCommon/FolderTreeWidget"
Laurent Montel's avatar
Port++  
Laurent Montel committed
34
#include "util.h"
Laurent Montel's avatar
Laurent Montel committed
35 36
#include "mailcommon/mailutil.h"
#include "mailcommon/mailkernel.h"
Laurent Montel's avatar
Laurent Montel committed
37
#include "dialog/archivefolderdialog.h"
Laurent Montel's avatar
Laurent Montel committed
38
#include "settings/kmailsettings.h"
Laurent Montel's avatar
Laurent Montel committed
39
#include "MailCommon/FolderTreeView"
Laurent Montel's avatar
Laurent Montel committed
40
#include "tag/tagactionmanager.h"
41
#include "foldershortcutactionmanager.h"
Laurent Montel's avatar
Laurent Montel committed
42
#include "widgets/collectionpane.h"
43
#include "manageshowcollectionproperties.h"
44
#include "widgets/kactionmenutransport.h"
45
#include "widgets/kactionmenuaccount.h"
46
#include "mailcommon/searchrulestatus.h"
Laurent Montel's avatar
Laurent Montel committed
47
#include "plugininterface/kmailplugininterface.h"
Laurent Montel's avatar
Laurent Montel committed
48
#include "PimCommon/NetworkUtil"
Laurent Montel's avatar
Laurent Montel committed
49
#include "kpimtextedit/texttospeech.h"
50
#include "job/markallmessagesasreadinfolderandsubfolderjob.h"
51
#include "job/removeduplicatemessageinfolderandsubfolderjob.h"
52
#if !defined(NDEBUG)
Laurent Montel's avatar
Laurent Montel committed
53
#include <KSieveUi/SieveDebugDialog>
Laurent Montel's avatar
Laurent Montel committed
54
using KSieveUi::SieveDebugDialog;
55
#endif
56

Laurent Montel's avatar
Laurent Montel committed
57 58 59 60 61 62
#include "collectionpage/collectionmaintenancepage.h"
#include "collectionpage/collectionquotapage.h"
#include "collectionpage/collectiontemplatespage.h"
#include "collectionpage/collectionshortcutpage.h"
#include "collectionpage/collectionviewpage.h"
#include "collectionpage/collectionmailinglistpage.h"
Laurent Montel's avatar
Laurent Montel committed
63
#include "tag/tagselectdialog.h"
Laurent Montel's avatar
Laurent Montel committed
64
#include "job/createnewcontactjob.h"
65 66
#include "folderarchive/folderarchiveutil.h"
#include "folderarchive/folderarchivemanager.h"
67

Laurent Montel's avatar
Laurent Montel committed
68 69
#include "PimCommon/CollectionAclPage"
#include "PimCommon/PimUtil"
Laurent Montel's avatar
Laurent Montel committed
70 71 72 73 74 75 76 77
#include "MailCommon/CollectionGeneralPage"
#include "MailCommon/CollectionExpiryPage"
#include "MailCommon/ExpireCollectionAttribute"
#include "MailCommon/FilterManager"
#include "MailCommon/MailFilter"
#include "MailCommon/FavoriteCollectionWidget"
#include "MailCommon/FolderTreeWidget"
#include "MailCommon/FolderTreeView"
Laurent Montel's avatar
Laurent Montel committed
78
#include "mailcommonsettings_base.h"
Stephen Kelly's avatar
Stephen Kelly committed
79
#include "kmmainwidget.h"
80

Thomas McGuire's avatar
Thomas McGuire committed
81
// Other PIM includes
82
#include "kmail-version.h"
83

84
#include "messageviewer/messageviewersettings.h"
85
#include "messageviewer/viewer.h"
Laurent Montel's avatar
Laurent Montel committed
86 87
#include "messageviewer/headerstyleplugin.h"
#include "messageviewer/headerstyle.h"
88 89 90

#include <MimeTreeParser/AttachmentStrategy>

91
#ifndef QT_NO_CURSOR
92
#include "Libkdepim/KCursorSaver"
93
#endif
94

Laurent Montel's avatar
Laurent Montel committed
95 96
#include "MessageComposer/MessageSender"
#include "MessageComposer/MessageHelper"
97

98
#include "TemplateParser/TemplateParser"
99

Laurent Montel's avatar
Laurent Montel committed
100
#include <MessageCore/MessageCoreSettings>
Laurent Montel's avatar
Laurent Montel committed
101
#include "MessageCore/MailingList"
Laurent Montel's avatar
Laurent Montel committed
102
#include "messagecore/messagehelpers.h"
103

Laurent Montel's avatar
Laurent Montel committed
104
#include "dialog/kmknotify.h"
105
#include "widgets/displaymessageformatactionmenu.h"
106

107
#include "ksieveui/vacationmanager.h"
108
#include "kmlaunchexternalcomponent.h"
Laurent Montel's avatar
Laurent Montel committed
109

Thomas McGuire's avatar
Thomas McGuire committed
110
// LIBKDEPIM includes
Laurent Montel's avatar
Laurent Montel committed
111
#include "libkdepim/progressmanager.h"
Laurent Montel's avatar
Laurent Montel committed
112
#include "libkdepim/broadcaststatus.h"
113

Thomas McGuire's avatar
Thomas McGuire committed
114
// KDEPIMLIBS includes
Laurent Montel's avatar
Laurent Montel committed
115
#include <AkonadiCore/AgentManager>
Laurent Montel's avatar
Laurent Montel committed
116 117
#include <AkonadiCore/AttributeFactory>
#include <AkonadiCore/itemfetchjob.h>
Laurent Montel's avatar
Laurent Montel committed
118
#include <AkonadiCore/collectionattributessynchronizationjob.h>
Laurent Montel's avatar
Laurent Montel committed
119 120
#include <AkonadiCore/collectionfetchjob.h>
#include <AkonadiCore/collectionfetchscope.h>
121
#include <Akonadi/Contact/ContactSearchJob>
Laurent Montel's avatar
Laurent Montel committed
122
#include <AkonadiWidgets/collectionpropertiesdialog.h>
Laurent Montel's avatar
Laurent Montel committed
123
#include <AkonadiCore/entitydisplayattribute.h>
Laurent Montel's avatar
Laurent Montel committed
124 125
#include <AkonadiWidgets/entitylistview.h>
#include <AkonadiWidgets/etmviewstatesaver.h>
Laurent Montel's avatar
Laurent Montel committed
126 127 128 129 130
#include <AkonadiCore/agentinstance.h>
#include <AkonadiCore/agenttype.h>
#include <AkonadiCore/changerecorder.h>
#include <AkonadiCore/session.h>
#include <AkonadiCore/entitytreemodel.h>
Laurent Montel's avatar
Laurent Montel committed
131
#include <AkonadiCore/favoritecollectionsmodel.h>
Laurent Montel's avatar
Laurent Montel committed
132 133
#include <AkonadiCore/itemfetchscope.h>
#include <AkonadiCore/itemmodifyjob.h>
Laurent Montel's avatar
Laurent Montel committed
134
#include <AkonadiWidgets/controlgui.h>
Laurent Montel's avatar
Laurent Montel committed
135
#include <AkonadiWidgets/collectiondialog.h>
Laurent Montel's avatar
Laurent Montel committed
136
#include <AkonadiCore/collectionstatistics.h>
Laurent Montel's avatar
Laurent Montel committed
137
#include <AkonadiCore/EntityMimeTypeFilterModel>
138
#include <Akonadi/KMime/MessageFlags>
Laurent Montel's avatar
Laurent Montel committed
139
#include <AkonadiCore/CachePolicy>
140

Laurent Montel's avatar
Laurent Montel committed
141 142
#include <kidentitymanagement/identity.h>
#include <kidentitymanagement/identitymanager.h>
143
#include <KEmailAddress>
Laurent Montel's avatar
Laurent Montel committed
144 145 146
#include <mailtransport/transportmanager.h>
#include <mailtransport/transport.h>
#include <kmime/kmime_mdn.h>
Laurent Montel's avatar
Laurent Montel committed
147 148
#include <kmime/kmime_header_parsing.h>
#include <kmime/kmime_message.h>
149 150
#include <ksieveui/managesievescriptsdialog.h>
#include <ksieveui/util.h>
151

Thomas McGuire's avatar
Thomas McGuire committed
152 153 154 155
// KDELIBS includes
#include <kwindowsystem.h>
#include <kmessagebox.h>
#include <kactionmenu.h>
Laurent Montel's avatar
Laurent Montel committed
156
#include <QMenu>
Thomas McGuire's avatar
Thomas McGuire committed
157 158 159
#include <kacceleratormanager.h>
#include <kstandardshortcut.h>
#include <kcharsets.h>
Laurent Montel's avatar
Laurent Montel committed
160
#include "kmail_debug.h"
Thomas McGuire's avatar
Thomas McGuire committed
161
#include <ktip.h>
Laurent Montel's avatar
Laurent Montel committed
162

Thomas McGuire's avatar
Thomas McGuire committed
163 164 165 166 167 168 169 170 171
#include <kstandardaction.h>
#include <ktoggleaction.h>
#include <knotification.h>
#include <knotifyconfigwidget.h>
#include <kstringhandler.h>
#include <kconfiggroup.h>
#include <ktoolinvocation.h>
#include <kxmlguifactory.h>
#include <kxmlguiclient.h>
Laurent Montel's avatar
Laurent Montel committed
172 173
#include <QStatusBar>
#include <QAction>
Thomas McGuire's avatar
Thomas McGuire committed
174
#include <ktreewidgetsearchline.h>
Laurent Montel's avatar
Laurent Montel committed
175
#include <KRecentFilesAction>
176

Thomas McGuire's avatar
Thomas McGuire committed
177 178
// Qt includes
#include <QByteArray>
179
#include <QHeaderView>
Thomas McGuire's avatar
Thomas McGuire committed
180 181 182 183 184
#include <QList>
#include <QSplitter>
#include <QVBoxLayout>
#include <QShortcut>
#include <QProcess>
185
#include <QDBusConnection>
186
#include <QTextDocument>
187
#include <QDir>
188
#include <WebEngineViewer/WebHitTestResult>
Thomas McGuire's avatar
Thomas McGuire committed
189
// System includes
Laurent Montel's avatar
Laurent Montel committed
190
#include <AkonadiWidgets/standardactionmanager.h>
191
#include <KHelpClient>
Laurent Montel's avatar
Laurent Montel committed
192
#include <QStandardPaths>
193

Laurent Montel's avatar
Laurent Montel committed
194
#include "PimCommon/ManageServerSideSubscriptionJob"
195
#include <job/removeduplicatemailjob.h>
Laurent Montel's avatar
Laurent Montel committed
196
#include <job/removecollectionjob.h>
197

Thomas McGuire's avatar
Thomas McGuire committed
198
using namespace KMime;
199
using namespace Akonadi;
Andras Mantia's avatar
Andras Mantia committed
200
using namespace MailCommon;
Thomas McGuire's avatar
Thomas McGuire committed
201 202 203 204
using KPIM::ProgressManager;
using KPIM::BroadcastStatus;
using KMail::SearchWindow;
using KMime::Types::AddrSpecList;
205
using MimeTreeParser::AttachmentStrategy;
Stephan Kulow's avatar
Stephan Kulow committed
206

Laurent Montel's avatar
Laurent Montel committed
207
Q_GLOBAL_STATIC(KMMainWidget::PtrList, theMainWidgetList)
208

Stephan Kulow's avatar
Stephan Kulow committed
209
//-----------------------------------------------------------------------------
Laurent Montel's avatar
Laurent Montel committed
210 211 212
KMMainWidget::KMMainWidget(QWidget *parent, KXMLGUIClient *aGUIClient,
                           KActionCollection *actionCollection, KSharedConfig::Ptr config) :
    QWidget(parent),
Laurent Montel's avatar
Laurent Montel committed
213 214 215 216 217 218 219 220 221 222 223
    mMoveMsgToFolderAction(Q_NULLPTR),
    mCollectionProperties(Q_NULLPTR),
    mFavoriteCollectionsView(Q_NULLPTR),
    mMsgView(Q_NULLPTR),
    mSplitter1(Q_NULLPTR),
    mSplitter2(Q_NULLPTR),
    mFolderViewSplitter(Q_NULLPTR),
    mArchiveFolderAction(Q_NULLPTR),
    mShowBusySplashTimer(Q_NULLPTR),
    mMsgActions(Q_NULLPTR),
    mCurrentFolder(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
224 225
    mVacationIndicatorActive(false),
    mGoToFirstUnreadMessageInSelectedFolder(false),
Laurent Montel's avatar
Laurent Montel committed
226
    mDisplayMessageFormatMenu(Q_NULLPTR),
227
    mFolderDisplayFormatPreference(MessageViewer::Viewer::UseGlobalSetting),
Laurent Montel's avatar
Laurent Montel committed
228
    mSearchMessages(Q_NULLPTR),
229
    mManageShowCollectionProperties(new ManageShowCollectionProperties(this, this)),
230
    mShowIntroductionAction(Q_NULLPTR),
Laurent Montel's avatar
Laurent Montel committed
231
    mMarkAllMessageAsReadAndInAllSubFolder(Q_NULLPTR),
232 233
    mAccountActionMenu(Q_NULLPTR),
    mRemoveDuplicateRecursiveAction(Q_NULLPTR)
Stephan Kulow's avatar
Stephan Kulow committed
234
{
235
    mLaunchExternalComponent = new KMLaunchExternalComponent(this, this);
Laurent Montel's avatar
Laurent Montel committed
236 237 238 239 240
    // must be the first line of the constructor:
    mStartupDone = false;
    mWasEverShown = false;
    mReaderWindowActive = true;
    mReaderWindowBelow = true;
241
    mFolderHtmlLoadExtPreference = false;
Laurent Montel's avatar
Laurent Montel committed
242 243
    mDestructed = false;
    mActionCollection = actionCollection;
Laurent Montel's avatar
Laurent Montel committed
244 245
    mTopLayout = new QVBoxLayout(this);
    mTopLayout->setMargin(0);
Laurent Montel's avatar
Laurent Montel committed
246 247
    mConfig = config;
    mGUIClient = aGUIClient;
Laurent Montel's avatar
Laurent Montel committed
248 249
    mFolderTreeWidget = Q_NULLPTR;
    mPreferHtmlLoadExtAction = Q_NULLPTR;
Laurent Montel's avatar
Laurent Montel committed
250
    Akonadi::ControlGui::widgetNeedsAkonadi(this);
Laurent Montel's avatar
Laurent Montel committed
251
    mFavoritesModel = Q_NULLPTR;
Laurent Montel's avatar
Laurent Montel committed
252
    mVacationManager = new KSieveUi::VacationManager(this);
253
    connect(mVacationManager, SIGNAL(updateVacationScriptStatus(bool,QString)), SLOT(updateVacationScriptStatus(bool,QString)));
Laurent Montel's avatar
Laurent Montel committed
254

Laurent Montel's avatar
Laurent Montel committed
255 256
    mToolbarActionSeparator = new QAction(this);
    mToolbarActionSeparator->setSeparator(true);
Laurent Montel's avatar
Laurent Montel committed
257

Laurent Montel's avatar
Laurent Montel committed
258
    mPluginInterface = new KMailPluginInterface(mActionCollection, this);
Laurent Montel's avatar
Laurent Montel committed
259
    mPluginInterface->setMainWidget(this);
Laurent Montel's avatar
Laurent Montel committed
260

Laurent Montel's avatar
Laurent Montel committed
261
    theMainWidgetList->append(this);
Laurent Montel's avatar
Laurent Montel committed
262 263 264 265 266 267 268

    readPreConfig();
    createWidgets();
    setupActions();

    readConfig();

Laurent Montel's avatar
Laurent Montel committed
269
    if (!kmkernel->isOffline()) {   //kmail is set to online mode, make sure the agents are also online
Laurent Montel's avatar
Laurent Montel committed
270 271 272
        kmkernel->setAccountStatus(true);
    }

273
    QTimer::singleShot(0, this, &KMMainWidget::slotShowStartupFolder);
Laurent Montel's avatar
Laurent Montel committed
274

275 276
    connect(kmkernel, &KMKernel::startCheckMail,
            this, &KMMainWidget::slotStartCheckMail);
Laurent Montel's avatar
Laurent Montel committed
277

278 279
    connect(kmkernel, &KMKernel::endCheckMail,
            this, &KMMainWidget::slotEndCheckMail);
Laurent Montel's avatar
Laurent Montel committed
280

281 282
    connect(kmkernel, &KMKernel::configChanged,
            this, &KMMainWidget::slotConfigChanged);
Laurent Montel's avatar
Laurent Montel committed
283

284 285
    connect(kmkernel, &KMKernel::onlineStatusChanged,
            this, &KMMainWidget::slotUpdateOnlineStatus);
Laurent Montel's avatar
Laurent Montel committed
286

Laurent Montel's avatar
Laurent Montel committed
287 288
    connect(mTagActionManager, &KMail::TagActionManager::tagActionTriggered,
            this, &KMMainWidget::slotUpdateMessageTagList);
Laurent Montel's avatar
Laurent Montel committed
289

Laurent Montel's avatar
Laurent Montel committed
290 291
    connect(mTagActionManager, &KMail::TagActionManager::tagMoreActionClicked,
            this, &KMMainWidget::slotSelectMoreMessageTagList);
Laurent Montel's avatar
Laurent Montel committed
292 293 294

    kmkernel->toggleSystemTray();

Laurent Montel's avatar
Laurent Montel committed
295 296
    {
        // make sure the pages are registered only once, since there can be multiple instances of KMMainWidget
Laurent Montel's avatar
Laurent Montel committed
297 298
        static bool pagesRegistered = false;

Laurent Montel's avatar
Laurent Montel committed
299 300 301 302 303 304 305 306 307 308
        if (!pagesRegistered) {
            Akonadi::CollectionPropertiesDialog::registerPage(new PimCommon::CollectionAclPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new MailCommon::CollectionGeneralPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new CollectionMaintenancePageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new CollectionQuotaPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new CollectionTemplatesPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new MailCommon::CollectionExpiryPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new CollectionViewPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new CollectionMailingListPageFactory);
            Akonadi::CollectionPropertiesDialog::registerPage(new CollectionShortcutPageFactory);
Laurent Montel's avatar
Laurent Montel committed
309 310 311 312 313

            pagesRegistered = true;
        }
    }

Laurent Montel's avatar
Laurent Montel committed
314
    KMainWindow *mainWin = dynamic_cast<KMainWindow *>(window());
Laurent Montel's avatar
Laurent Montel committed
315
    QStatusBar *sb =  mainWin ? mainWin->statusBar() : Q_NULLPTR;
Laurent Montel's avatar
Laurent Montel committed
316
    mVacationScriptIndicator = new KMail::VacationScriptIndicatorWidget(sb);
Laurent Montel's avatar
Laurent Montel committed
317
    mVacationScriptIndicator->hide();
Laurent Montel's avatar
Laurent Montel committed
318
    connect(mVacationScriptIndicator, &KMail::VacationScriptIndicatorWidget::clicked, this, &KMMainWidget::slotEditVacation);
Laurent Montel's avatar
Laurent Montel committed
319
    if (KSieveUi::Util::checkOutOfOfficeOnStartup()) {
320
        QTimer::singleShot(0, this, &KMMainWidget::slotCheckVacation);
Laurent Montel's avatar
Laurent Montel committed
321
    }
Laurent Montel's avatar
Laurent Montel committed
322

323 324
    connect(mFolderTreeWidget->folderTreeView()->model(), &QAbstractItemModel::modelReset,
            this, &KMMainWidget::restoreCollectionFolderViewConfig);
Laurent Montel's avatar
Laurent Montel committed
325 326
    restoreCollectionFolderViewConfig();

Laurent Montel's avatar
Laurent Montel committed
327
    if (kmkernel->firstStart()) {
Laurent Montel's avatar
Laurent Montel committed
328
        if (MailCommon::Util::foundMailer()) {
Laurent Montel's avatar
Laurent Montel committed
329
            if (KMessageBox::questionYesNo(this, i18n("Another mailer was found on system. Do you want to import data from it?")) == KMessageBox::Yes) {
Laurent Montel's avatar
Laurent Montel committed
330
                const QString path = QStandardPaths::findExecutable(QStringLiteral("importwizard"));
Laurent Montel's avatar
Laurent Montel committed
331 332 333 334
                if (!QProcess::startDetached(path)) {
                    KMessageBox::error(this, i18n("Could not start the import wizard. "
                                                  "Please check your installation."),
                                       i18n("Unable to start import wizard"));
Laurent Montel's avatar
Laurent Montel committed
335 336
                }
            } else {
337
                mLaunchExternalComponent->slotAccountWizard();
Laurent Montel's avatar
Laurent Montel committed
338 339
            }
        } else {
340
            mLaunchExternalComponent->slotAccountWizard();
341 342
        }
    }
Laurent Montel's avatar
Laurent Montel committed
343 344
    // must be the last line of the constructor:
    mStartupDone = true;
345

Laurent Montel's avatar
Laurent Montel committed
346 347
    mCheckMailTimer.setInterval(3 * 1000);
    mCheckMailTimer.setSingleShot(true);
Laurent Montel's avatar
Laurent Montel committed
348
    connect(&mCheckMailTimer, &QTimer::timeout, this, &KMMainWidget::slotUpdateActionsAfterMailChecking);
349

350 351
}

352
void KMMainWidget::restoreCollectionFolderViewConfig()
353
{
Laurent Montel's avatar
Laurent Montel committed
354
    ETMViewStateSaver *saver = new ETMViewStateSaver;
Laurent Montel's avatar
Laurent Montel committed
355 356 357 358
    saver->setView(mFolderTreeWidget->folderTreeView());
    const KConfigGroup cfg(KMKernel::self()->config(), "CollectionFolderView");
    mFolderTreeWidget->restoreHeaderState(cfg.readEntry("HeaderState", QByteArray()));
    saver->restoreState(cfg);
Laurent Montel's avatar
Laurent Montel committed
359
    //Restore startup folder
360

Laurent Montel's avatar
Laurent Montel committed
361
    Akonadi::Collection::Id id = -1;
Laurent Montel's avatar
Laurent Montel committed
362
    if (mCurrentFolder && mCurrentFolder->collection().isValid()) {
Laurent Montel's avatar
Laurent Montel committed
363 364
        id = mCurrentFolder->collection().id();
    }
365

Laurent Montel's avatar
Laurent Montel committed
366
    if (id == -1) {
Laurent Montel's avatar
Laurent Montel committed
367 368
        if (KMailSettings::self()->startSpecificFolderAtStartup()) {
            Akonadi::Collection::Id startupFolder = KMailSettings::self()->startupFolder();
Laurent Montel's avatar
Laurent Montel committed
369
            if (startupFolder > 0) {
Laurent Montel's avatar
Laurent Montel committed
370
                saver->restoreCurrentItem(QStringLiteral("c%1").arg(startupFolder));
Laurent Montel's avatar
Laurent Montel committed
371
            }
Laurent Montel's avatar
Laurent Montel committed
372 373
        }
    } else {
Laurent Montel's avatar
Laurent Montel committed
374
        saver->restoreCurrentItem(QStringLiteral("c%1").arg(id));
375
    }
Stephan Kulow's avatar
Stephan Kulow committed
376 377 378 379 380
}

//-----------------------------------------------------------------------------
//The kernel may have already been deleted when this method is called,
//perform all cleanup that requires the kernel in destruct()
381
KMMainWidget::~KMMainWidget()
Stephan Kulow's avatar
Stephan Kulow committed
382
{
Laurent Montel's avatar
Laurent Montel committed
383 384
    theMainWidgetList->removeAll(this);
    qDeleteAll(mFilterCommands);
Laurent Montel's avatar
Laurent Montel committed
385
    destruct();
Stephan Kulow's avatar
Stephan Kulow committed
386 387 388 389
}

//-----------------------------------------------------------------------------
//This method performs all cleanup that requires the kernel to exist.
390
void KMMainWidget::destruct()
Stephan Kulow's avatar
Stephan Kulow committed
391
{
Laurent Montel's avatar
Laurent Montel committed
392
    if (mDestructed) {
Laurent Montel's avatar
Laurent Montel committed
393
        return;
Laurent Montel's avatar
Laurent Montel committed
394 395
    }
    if (mSearchWin) {
Laurent Montel's avatar
Laurent Montel committed
396
        mSearchWin->close();
Laurent Montel's avatar
Laurent Montel committed
397
    }
398
    disconnect(mFolderTreeWidget->folderTreeView()->selectionModel(), &QItemSelectionModel::selectionChanged, this, &KMMainWidget::updateFolderMenu);
Laurent Montel's avatar
Laurent Montel committed
399 400 401 402 403 404
    writeConfig(false); /* don't force kmkernel sync when close BUG: 289287 */
    writeFolderConfig();
    deleteWidgets();
    mCurrentFolder.clear();
    delete mMoveOrCopyToDialog;
    delete mSelectFromAllFoldersDialog;
Laurent Montel's avatar
Laurent Montel committed
405

Laurent Montel's avatar
Laurent Montel committed
406 407 408 409 410
    disconnect(kmkernel->folderCollectionMonitor(), SIGNAL(itemAdded(Akonadi::Item,Akonadi::Collection)), this, Q_NULLPTR);
    disconnect(kmkernel->folderCollectionMonitor(), SIGNAL(itemRemoved(Akonadi::Item)), this, Q_NULLPTR);
    disconnect(kmkernel->folderCollectionMonitor(), SIGNAL(itemMoved(Akonadi::Item,Akonadi::Collection,Akonadi::Collection)), this, Q_NULLPTR);
    disconnect(kmkernel->folderCollectionMonitor(), SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)), this, Q_NULLPTR);
    disconnect(kmkernel->folderCollectionMonitor(), SIGNAL(collectionStatisticsChanged(Akonadi::Collection::Id,Akonadi::CollectionStatistics)), this, Q_NULLPTR);
Laurent Montel's avatar
Laurent Montel committed
411

Laurent Montel's avatar
Laurent Montel committed
412
    mDestructed = true;
Stephan Kulow's avatar
Stephan Kulow committed
413 414
}

415 416
void KMMainWidget::slotStartCheckMail()
{
Laurent Montel's avatar
Laurent Montel committed
417
    if (mCheckMailTimer.isActive()) {
Laurent Montel's avatar
Laurent Montel committed
418
        mCheckMailTimer.stop();
Laurent Montel's avatar
Laurent Montel committed
419
    }
420 421 422 423
}

void KMMainWidget::slotEndCheckMail()
{
Laurent Montel's avatar
Laurent Montel committed
424
    if (!mCheckMailTimer.isActive()) {
Laurent Montel's avatar
Laurent Montel committed
425
        mCheckMailTimer.start();
Laurent Montel's avatar
Laurent Montel committed
426
    }
427 428
}

Laurent Montel's avatar
Laurent Montel committed
429
void KMMainWidget::slotUpdateActionsAfterMailChecking()
430
{
Laurent Montel's avatar
Laurent Montel committed
431
    const bool sendOnAll =
Laurent Montel's avatar
Laurent Montel committed
432
        KMailSettings::self()->sendOnCheck() == KMailSettings::EnumSendOnCheck::SendOnAllChecks;
Laurent Montel's avatar
Laurent Montel committed
433
    const bool sendOnManual =
Laurent Montel's avatar
Laurent Montel committed
434
        KMailSettings::self()->sendOnCheck() == KMailSettings::EnumSendOnCheck::SendOnManualChecks;
Laurent Montel's avatar
Laurent Montel committed
435
    if (!kmkernel->isOffline() && (sendOnAll || sendOnManual)) {
Laurent Montel's avatar
Laurent Montel committed
436 437 438 439 440
        slotSendQueued();
    }
    // update folder menus in case some mail got filtered to trash/current folder
    // and we can enable "empty trash/move all to trash" action etc.
    updateFolderMenu();
441 442
}

Laurent Montel's avatar
Laurent Montel committed
443
void KMMainWidget::slotCollectionFetched(int collectionId)
444
{
Laurent Montel's avatar
Laurent Montel committed
445 446 447
    // Called when a collection is fetched for the first time by the ETM.
    // This is the right time to update the caption (which still says "Loading...")
    // and to update the actions that depend on the number of mails in the folder.
Laurent Montel's avatar
Laurent Montel committed
448 449
    if (mCurrentFolder && collectionId == mCurrentFolder->collection().id()) {
        mCurrentFolder->setCollection(MailCommon::Util::updatedCollection(mCurrentFolder->collection()));
Laurent Montel's avatar
Laurent Montel committed
450 451 452 453
        updateMessageActions();
        updateFolderMenu();
    }
    // We call this for any collection, it could be one of our parents...
Laurent Montel's avatar
Laurent Montel committed
454
    if (mCurrentFolder) {
Laurent Montel's avatar
Laurent Montel committed
455
        Q_EMIT captionChangeRequest(MailCommon::Util::fullCollectionPath(mCurrentFolder->collection()));
Laurent Montel's avatar
Laurent Montel committed
456
    }
457 458
}

Laurent Montel's avatar
Laurent Montel committed
459
void KMMainWidget::slotFolderChanged(const Akonadi::Collection &collection)
460
{
Laurent Montel's avatar
Laurent Montel committed
461 462 463 464 465
    folderSelected(collection);
    if (collection.cachePolicy().syncOnDemand()) {
        AgentManager::self()->synchronizeCollection(collection, false);
    }
    mMsgActions->setCurrentMessage(Akonadi::Item());
Laurent Montel's avatar
Laurent Montel committed
466
    Q_EMIT captionChangeRequest(MailCommon::Util::fullCollectionPath(collection));
Laurent Montel's avatar
Laurent Montel committed
467 468
}

Laurent Montel's avatar
Laurent Montel committed
469
void KMMainWidget::folderSelected(const Akonadi::Collection &col)
Laurent Montel's avatar
Laurent Montel committed
470
{
Laurent Montel's avatar
Laurent Montel committed
471
    // This is connected to the MainFolderView signal triggering when a folder is selected
Laurent Montel's avatar
Laurent Montel committed
472

Laurent Montel's avatar
Laurent Montel committed
473
    if (mGoToFirstUnreadMessageInSelectedFolder) {
Laurent Montel's avatar
Laurent Montel committed
474
        // the default action has been overridden from outside
475
        mPreSelectionMode = MessageList::Core::PreSelectFirstUnreadCentered;
Laurent Montel's avatar
Laurent Montel committed
476 477
    } else {
        // use the default action
Laurent Montel's avatar
Laurent Montel committed
478 479
        switch (KMailSettings::self()->actionEnterFolder()) {
        case KMailSettings::EnumActionEnterFolder::SelectFirstUnread:
Laurent Montel's avatar
Laurent Montel committed
480 481
            mPreSelectionMode = MessageList::Core::PreSelectFirstUnreadCentered;
            break;
Laurent Montel's avatar
Laurent Montel committed
482
        case KMailSettings::EnumActionEnterFolder::SelectLastSelected:
Laurent Montel's avatar
Laurent Montel committed
483 484
            mPreSelectionMode = MessageList::Core::PreSelectLastSelected;
            break;
Laurent Montel's avatar
Laurent Montel committed
485
        case KMailSettings::EnumActionEnterFolder::SelectNewest:
Laurent Montel's avatar
Laurent Montel committed
486 487
            mPreSelectionMode = MessageList::Core::PreSelectNewestCentered;
            break;
Laurent Montel's avatar
Laurent Montel committed
488
        case KMailSettings::EnumActionEnterFolder::SelectOldest:
Laurent Montel's avatar
Laurent Montel committed
489 490 491 492 493 494 495 496 497
            mPreSelectionMode = MessageList::Core::PreSelectOldestCentered;
            break;
        default:
            mPreSelectionMode = MessageList::Core::PreSelectNone;
            break;
        }
    }

    mGoToFirstUnreadMessageInSelectedFolder = false;
498
#ifndef QT_NO_CURSOR
499
    KPIM::KCursorSaver busy(KPIM::KBusyPtr::busy());
500
#endif
Laurent Montel's avatar
Laurent Montel committed
501

Laurent Montel's avatar
Laurent Montel committed
502
    if (mMsgView) {
Laurent Montel's avatar
Laurent Montel committed
503
        mMsgView->clear(true);
Laurent Montel's avatar
Laurent Montel committed
504 505
    }
    const bool newFolder = mCurrentFolder && (mCurrentFolder->collection() != col);
David Faure's avatar
David Faure committed
506

Laurent Montel's avatar
Laurent Montel committed
507 508
    // Delete any pending timer, if needed it will be recreated below
    delete mShowBusySplashTimer;
Laurent Montel's avatar
Laurent Montel committed
509
    mShowBusySplashTimer = Q_NULLPTR;
Laurent Montel's avatar
Laurent Montel committed
510
    if (newFolder) {
Laurent Montel's avatar
Laurent Montel committed
511 512 513
        // We're changing folder: write configuration for the old one
        writeFolderConfig();
    }
Laurent Montel's avatar
Laurent Montel committed
514

Laurent Montel's avatar
Laurent Montel committed
515
    mCurrentFolder = FolderCollection::forCollection(col);
Laurent Montel's avatar
Laurent Montel committed
516

Laurent Montel's avatar
Laurent Montel committed
517
    readFolderConfig();
Laurent Montel's avatar
Laurent Montel committed
518
    if (mMsgView) {
519
        mMsgView->setDisplayFormatMessageOverwrite(mFolderDisplayFormatPreference);
520
        mMsgView->setHtmlLoadExtOverride(mFolderHtmlLoadExtPreference);
Laurent Montel's avatar
Laurent Montel committed
521
    }
Laurent Montel's avatar
Laurent Montel committed
522

Laurent Montel's avatar
Laurent Montel committed
523
    if (!mCurrentFolder->isValid() && (mMessagePane->count() < 2)) {
Laurent Montel's avatar
Laurent Montel committed
524
        slotIntro();
Laurent Montel's avatar
Laurent Montel committed
525
    }
Laurent Montel's avatar
Laurent Montel committed
526

Laurent Montel's avatar
Laurent Montel committed
527 528
    updateMessageActions();
    updateFolderMenu();
529

Laurent Montel's avatar
Laurent Montel committed
530 531 532
    // The message pane uses the selection model of the folder view to load the correct aggregation model and theme
    //  settings. At this point the selection model hasn't been updated yet to the user's new choice, so it would load
    //  the old folder settings instead.
533
    QTimer::singleShot(0, this, &KMMainWidget::slotShowSelectedFolderInPane);
534 535
}

Laurent Montel's avatar
Laurent Montel committed
536
void KMMainWidget::slotShowSelectedFolderInPane()
537
{
Laurent Montel's avatar
Laurent Montel committed
538
    if (mCurrentFolder && mCurrentFolder->collection().isValid()) {
Laurent Montel's avatar
Laurent Montel committed
539
        mMessagePane->setCurrentFolder(mCurrentFolder->collection(), false, mPreSelectionMode);
Laurent Montel's avatar
Laurent Montel committed
540
    }
541 542
}

543 544
void KMMainWidget::clearViewer()
{
Laurent Montel's avatar
Laurent Montel committed
545
    if (mMsgView) {
Laurent Montel's avatar
Laurent Montel committed
546
        mMsgView->clear(true);
Laurent Montel's avatar
Laurent Montel committed
547 548
        mMsgView->displayAboutPage();
    }
549
}
550

Stephan Kulow's avatar
Stephan Kulow committed
551
//-----------------------------------------------------------------------------
552
void KMMainWidget::readPreConfig()
Stephan Kulow's avatar
Stephan Kulow committed
553
{
Laurent Montel's avatar
Laurent Montel committed
554 555 556
    mLongFolderList = KMailSettings::self()->folderList() == KMailSettings::EnumFolderList::longlist;
    mReaderWindowActive = KMailSettings::self()->readerWindowMode() != KMailSettings::EnumReaderWindowMode::hide;
    mReaderWindowBelow = KMailSettings::self()->readerWindowMode() == KMailSettings::EnumReaderWindowMode::below;
Dirk Mueller's avatar
Dirk Mueller committed
557

Laurent Montel's avatar
Laurent Montel committed
558 559
    mHtmlGlobalSetting = MessageViewer::MessageViewerSettings::self()->htmlMail();
    mHtmlLoadExtGlobalSetting = MessageViewer::MessageViewerSettings::self()->htmlLoadExternal();
Laurent Montel's avatar
Laurent Montel committed
560

Laurent Montel's avatar
Laurent Montel committed
561
    mEnableFavoriteFolderView = (MailCommon::MailCommonSettings::self()->favoriteCollectionViewMode() != MailCommon::MailCommonSettings::EnumFavoriteCollectionViewMode::HiddenMode);
562
    readFolderConfig();
Laurent Montel's avatar
Laurent Montel committed
563
    updateHtmlMenuEntry();
564 565
    if (mMsgView) {
        mMsgView->setDisplayFormatMessageOverwrite(mFolderDisplayFormatPreference);
Laurent Montel's avatar
Laurent Montel committed
566
        mMsgView->update(true);
567
    }
Stephan Kulow's avatar
Stephan Kulow committed
568 569 570
}

//-----------------------------------------------------------------------------
571
void KMMainWidget::readFolderConfig()
Stephan Kulow's avatar
Stephan Kulow committed
572
{
Laurent Montel's avatar
Laurent Montel committed
573
    if (!mCurrentFolder || !mCurrentFolder->isValid()) {
Laurent Montel's avatar
Laurent Montel committed
574
        return;
Laurent Montel's avatar
Laurent Montel committed
575
    }
Laurent Montel's avatar
Laurent Montel committed
576
    KSharedConfig::Ptr config = KMKernel::self()->config();
Laurent Montel's avatar
Laurent Montel committed
577 578 579
    KConfigGroup group(config, MailCommon::FolderCollection::configGroupName(mCurrentFolder->collection()));
    if (group.hasKey("htmlMailOverride")) {
        const bool useHtml = group.readEntry("htmlMailOverride", false);
580 581 582 583
        mFolderDisplayFormatPreference = useHtml ? MessageViewer::Viewer::Html : MessageViewer::Viewer::Text;
        group.deleteEntry("htmlMailOverride");
        group.sync();
    } else {
Laurent Montel's avatar
Laurent Montel committed
584
        mFolderDisplayFormatPreference = static_cast<MessageViewer::Viewer::DisplayFormatMessage>(group.readEntry("displayFormatOverride", static_cast<int>(MessageViewer::Viewer::UseGlobalSetting)));
585
    }
586
    mFolderHtmlLoadExtPreference =
Laurent Montel's avatar
Laurent Montel committed
587
        group.readEntry("htmlLoadExternalOverride", false);
Stephan Kulow's avatar
Stephan Kulow committed
588 589 590
}

//-----------------------------------------------------------------------------
591
void KMMainWidget::writeFolderConfig()
Stephan Kulow's avatar
Stephan Kulow committed
592
{
Laurent Montel's avatar
Laurent Montel committed
593
    if (mCurrentFolder && mCurrentFolder->isValid()) {
Laurent Montel's avatar
Laurent Montel committed
594
        KSharedConfig::Ptr config = KMKernel::self()->config();
Laurent Montel's avatar
Laurent Montel committed
595 596 597
        KConfigGroup group(config, MailCommon::FolderCollection::configGroupName(mCurrentFolder->collection()));
        group.writeEntry("htmlLoadExternalOverride", mFolderHtmlLoadExtPreference);
        if (mFolderDisplayFormatPreference == MessageViewer::Viewer::UseGlobalSetting) {
598
            group.deleteEntry("displayFormatOverride");
Laurent Montel's avatar
Laurent Montel committed
599 600 601
        } else {
            group.writeEntry("displayFormatOverride", static_cast<int>(mFolderDisplayFormatPreference));
        }
Laurent Montel's avatar
Laurent Montel committed
602
    }
Stephan Kulow's avatar
Stephan Kulow committed
603 604
}

605 606 607
//-----------------------------------------------------------------------------
void KMMainWidget::layoutSplitters()
{
Laurent Montel's avatar
Laurent Montel committed
608
    // This function can only be called when the old splitters are already deleted
Laurent Montel's avatar
Laurent Montel committed
609 610
    Q_ASSERT(!mSplitter1);
    Q_ASSERT(!mSplitter2);
611

Laurent Montel's avatar
Laurent Montel committed
612 613
    // For some reason, this is necessary here so that the copy action still
    // works after changing the folder layout.
Laurent Montel's avatar
Laurent Montel committed
614
    if (mMsgView)
Laurent Montel's avatar
Laurent Montel committed
615 616
        disconnect(mMsgView->copyAction(), &QAction::triggered,
                   mMsgView, &KMReaderWin::slotCopySelectedText);
Laurent Montel's avatar
Laurent Montel committed
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631

    // If long folder list is enabled, the splitters are:
    // Splitter 1: FolderView vs (HeaderAndSearch vs MessageViewer)
    // Splitter 2: HeaderAndSearch vs MessageViewer
    //
    // If long folder list is disabled, the splitters are:
    // Splitter 1: (FolderView vs HeaderAndSearch) vs MessageViewer
    // Splitter 2: FolderView vs HeaderAndSearch

    // The folder view is both the folder tree and the favorite folder view, if
    // enabled

    const bool readerWindowAtSide = !mReaderWindowBelow && mReaderWindowActive;
    const bool readerWindowBelow = mReaderWindowBelow && mReaderWindowActive;

Laurent Montel's avatar
Laurent Montel committed
632 633
    mSplitter1 = new QSplitter(this);
    mSplitter2 = new QSplitter(mSplitter1);
Laurent Montel's avatar
Laurent Montel committed
634

Laurent Montel's avatar
Laurent Montel committed
635 636 637
    QWidget *folderTreeWidget = mSearchAndTree;
    if (mFavoriteCollectionsView) {
        mFolderViewSplitter = new QSplitter(Qt::Vertical);
Laurent Montel's avatar
Laurent Montel committed
638
        mFolderViewSplitter->setChildrenCollapsible(false);
Laurent Montel's avatar
Laurent Montel committed
639 640 641
        mFolderViewSplitter->addWidget(mFavoriteCollectionsView);
        mFavoriteCollectionsView->setParent(mFolderViewSplitter);
        mFolderViewSplitter->addWidget(mSearchAndTree);
Laurent Montel's avatar
Laurent Montel committed
642
        folderTreeWidget = mFolderViewSplitter;
Till Adam's avatar
Till Adam committed
643
    }
644

Laurent Montel's avatar
Laurent Montel committed
645
    if (mLongFolderList) {
Laurent Montel's avatar
Laurent Montel committed
646 647

        // add folder tree
Laurent Montel's avatar
Laurent Montel committed
648 649
        mSplitter1->setOrientation(Qt::Horizontal);
        mSplitter1->addWidget(folderTreeWidget);
Laurent Montel's avatar
Laurent Montel committed
650 651

        // and the rest to the right
Laurent Montel's avatar
Laurent Montel committed
652
        mSplitter1->addWidget(mSplitter2);
Laurent Montel's avatar
Laurent Montel committed
653 654

        // add the message list to the right or below
Laurent Montel's avatar
Laurent Montel committed
655 656
        if (readerWindowAtSide) {
            mSplitter2->setOrientation(Qt::Horizontal);
Laurent Montel's avatar
Laurent Montel committed
657
        } else {
Laurent Montel's avatar
Laurent Montel committed
658
            mSplitter2->setOrientation(Qt::Vertical);
Laurent Montel's avatar
Laurent Montel committed
659
        }
Laurent Montel's avatar
Laurent Montel committed
660
        mSplitter2->addWidget(mMessagePane);
Laurent Montel's avatar
Laurent Montel committed
661 662

        // add the preview window, if there is one
Laurent Montel's avatar
Laurent Montel committed
663 664
        if (mMsgView) {
            mSplitter2->addWidget(mMsgView);
Laurent Montel's avatar
Laurent Montel committed
665 666 667
        }

    } else { // short folder list
Laurent Montel's avatar
Laurent Montel committed
668 669 670
        if (mReaderWindowBelow) {
            mSplitter1->setOrientation(Qt::Vertical);
            mSplitter2->setOrientation(Qt::Horizontal);
Laurent Montel's avatar
Laurent Montel committed
671
        } else { // at side or none
Laurent Montel's avatar
Laurent Montel committed
672 673
            mSplitter1->setOrientation(Qt::Horizontal);
            mSplitter2->setOrientation(Qt::Vertical);
Laurent Montel's avatar
Laurent Montel committed
674 675
        }

Laurent Montel's avatar
Laurent Montel committed
676
        mSplitter1->addWidget(mSplitter2);
Laurent Montel's avatar
Laurent Montel committed
677 678

        // add folder tree
Laurent Montel's avatar
Laurent Montel committed
679
        mSplitter2->addWidget(folderTreeWidget);
Laurent Montel's avatar
Laurent Montel committed
680
        // add message list to splitter 2
Laurent Montel's avatar
Laurent Montel committed
681
        mSplitter2->addWidget(mMessagePane);
Laurent Montel's avatar
Laurent Montel committed
682 683

        // add the preview window, if there is one
Laurent Montel's avatar
Laurent Montel committed
684 685 686
        if (mMsgView) {
            mSplitter1->addWidget(mMsgView);
        }
Till Adam's avatar
Till Adam committed
687
    }
688

Laurent Montel's avatar
Laurent Montel committed
689 690 691
    //
    // Set splitter properties
    //
Laurent Montel's avatar
Laurent Montel committed
692
    mSplitter1->setObjectName(QStringLiteral("splitter1"));
Laurent Montel's avatar
Laurent Montel committed
693
    mSplitter1->setChildrenCollapsible(false);
Laurent Montel's avatar
Laurent Montel committed
694
    mSplitter2->setObjectName(QStringLiteral("splitter2"));
Laurent Montel's avatar
Laurent Montel committed
695
    mSplitter2->setChildrenCollapsible(false);
Laurent Montel's avatar
Laurent Montel committed
696 697 698 699

    //
    // Set the stretch factors
    //
Laurent Montel's avatar
Laurent Montel committed
700 701 702 703
    mSplitter1->setStretchFactor(0, 0);
    mSplitter2->setStretchFactor(0, 0);
    mSplitter1->setStretchFactor(1, 1);
    mSplitter2->setStretchFactor(1, 1);
Laurent Montel's avatar
Laurent Montel committed
704

Laurent Montel's avatar
Laurent Montel committed
705 706 707
    if (mFavoriteCollectionsView) {
        mFolderViewSplitter->setStretchFactor(0, 0);
        mFolderViewSplitter->setStretchFactor(1, 1);
Laurent Montel's avatar
Laurent Montel committed
708
    }
709

Laurent Montel's avatar
Laurent Montel committed
710 711 712
    // Because the reader windows's width increases a tiny bit after each
    // restart in short folder list mode with message window at side, disable
    // the stretching as a workaround here
Laurent Montel's avatar
Laurent Montel committed
713 714 715
    if (readerWindowAtSide && !mLongFolderList) {
        mSplitter1->setStretchFactor(0, 1);
        mSplitter1->setStretchFactor(1, 0);
Laurent Montel's avatar
Laurent Montel committed
716
    }
717

Laurent Montel's avatar
Laurent Montel committed
718 719 720 721 722 723
    //
    // Set the sizes of the splitters to the values stored in the config
    //
    QList<int> splitter1Sizes;
    QList<int> splitter2Sizes;

Laurent Montel's avatar
Laurent Montel committed
724 725 726 727 728 729
    const int folderViewWidth = KMailSettings::self()->folderViewWidth();
    int ftHeight = KMailSettings::self()->folderTreeHeight();
    int headerHeight = KMailSettings::self()->searchAndHeaderHeight();
    const int messageViewerWidth = KMailSettings::self()->readerWindowWidth();
    int headerWidth = KMailSettings::self()->searchAndHeaderWidth();
    int messageViewerHeight = KMailSettings::self()->readerWindowHeight();
Laurent Montel's avatar
Laurent Montel committed
730 731 732 733

    int ffvHeight = mFolderViewSplitter ? MailCommon::MailCommonSettings::self()->favoriteCollectionViewHeight() : 0;

    // If the message viewer was hidden before, make sure it is not zero height
Laurent Montel's avatar
Laurent Montel committed
734
    if (messageViewerHeight < 10 && readerWindowBelow) {
Laurent Montel's avatar
Laurent Montel committed
735 736
        headerHeight /= 2;
        messageViewerHeight = headerHeight;
737
    }
Laurent Montel's avatar
Laurent Montel committed
738

Laurent Montel's avatar
Laurent Montel committed
739 740
    if (mLongFolderList) {
        if (!readerWindowAtSide) {
Laurent Montel's avatar
Laurent Montel committed
741 742 743
            splitter1Sizes << folderViewWidth << headerWidth;
            splitter2Sizes << headerHeight << messageViewerHeight;
        } else {
Laurent Montel's avatar
Laurent Montel committed
744
            splitter1Sizes << folderViewWidth << (headerWidth + messageViewerWidth);
Laurent Montel's avatar
Laurent Montel committed
745 746
            splitter2Sizes << headerWidth << messageViewerWidth;
        }
747
    } else {
Laurent Montel's avatar
Laurent Montel committed
748
        if (!readerWindowAtSide) {
Laurent Montel's avatar
Laurent Montel committed
749 750 751 752 753 754
            splitter1Sizes << headerHeight << messageViewerHeight;
            splitter2Sizes << folderViewWidth << headerWidth;
        } else {
            splitter1Sizes << headerWidth << messageViewerWidth;
            splitter2Sizes << ftHeight + ffvHeight << messageViewerHeight;
        }
755 756
    }

Laurent Montel's avatar
Laurent Montel committed
757 758
    mSplitter1->setSizes(splitter1Sizes);
    mSplitter2->setSizes(splitter2Sizes);
759

Laurent Montel's avatar
Laurent Montel committed
760
    if (mFolderViewSplitter) {
Laurent Montel's avatar
Laurent Montel committed
761 762
        QList<int> splitterSizes;
        splitterSizes << ffvHeight << ftHeight;
Laurent Montel's avatar
Laurent Montel committed
763
        mFolderViewSplitter->setSizes(splitterSizes);
Laurent Montel's avatar
Laurent Montel committed
764
    }
765

Laurent Montel's avatar
Laurent Montel committed
766 767 768
    //
    // Now add the splitters to the main layout
    //
Laurent Montel's avatar
Laurent Montel committed
769
    mTopLayout->addWidget(mSplitter1);
770

Laurent Montel's avatar
Laurent Montel committed
771 772 773 774 775
    // Make sure the focus is on the view, and not on the quick search line edit, because otherwise
    // shortcuts like + or j go to the wrong place.
    // This would normally be done in the message list itself, but apparently something resets the focus
    // again, probably all the reparenting we do here.
    mMessagePane->focusView();
Laurent Montel's avatar
Laurent Montel committed
776

Laurent Montel's avatar
Laurent Montel committed
777
    // By default hide th unread and size columns on first run.
Laurent Montel's avatar
Laurent Montel committed
778 779 780 781
    if (kmkernel->firstStart()) {
        mFolderTreeWidget->folderTreeView()->hideColumn(1);
        mFolderTreeWidget->folderTreeView()->hideColumn(3);
        mFolderTreeWidget->folderTreeView()->header()->resizeSection(0, folderViewWidth * 0.8);
Laurent Montel's avatar
Laurent Montel committed
782
    }
783

Laurent Montel's avatar
Laurent Montel committed
784
    // Make the copy action work, see disconnect comment above
Laurent Montel's avatar
Laurent Montel committed
785
    if (mMsgView)
Laurent Montel's avatar
Laurent Montel committed
786 787
        connect(mMsgView->copyAction(), &QAction::triggered,
                mMsgView, &KMReaderWin::slotCopySelectedText);