collectionexpirypage.cpp 10.5 KB
Newer Older
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
  Copyright (c) 2009-2020 Laurent Montel <montel@kde.org>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  Copyright (c) 2013 Jonathan Marten <jjm@keelhaul.me.uk>

  This program 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.

  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
*/

#include "collectionexpirypage.h"

#include "attributes/expirecollectionattribute.h"
#include "folder/folderrequester.h"
23
#include "folder/foldersettings.h"
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include "util/mailutil.h"
#include "kernel/mailkernel.h"
#include "mailcommon_debug.h"

#include <CollectionModifyJob>

#include <KPluralHandlingSpinBox>
#include <KLocalizedString>
#include <KMessageBox>

#include <QCheckBox>
#include <QGroupBox>
#include <QPushButton>
#include <QRadioButton>
#include <QVBoxLayout>

using namespace Akonadi;
using namespace MailCommon;

CollectionExpiryPage::CollectionExpiryPage(QWidget *parent)
    : CollectionPropertiesPage(parent)
{
    setObjectName(QStringLiteral("MailCommon::CollectionExpiryPage"));
    setPageTitle(i18nc("@title:tab Expiry settings for a folder.", "Expiry"));
}

CollectionExpiryPage::~CollectionExpiryPage()
{
}

bool CollectionExpiryPage::canHandle(const Akonadi::Collection &col) const
{
56
    QSharedPointer<FolderSettings> fd = FolderSettings::forCollection(col, false);
57
    return fd->canDeleteMessages() && !fd->isStructural() && !MailCommon::Util::isVirtualCollection(col);
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
}

void CollectionExpiryPage::init()
{
    QVBoxLayout *globalVBox = new QVBoxLayout(this);

    QGridLayout *daysBox = new QGridLayout;

    expireReadMailCB = new QCheckBox;
    expireReadMailCB->setText(i18n("Expire read messages after"));
    connect(expireReadMailCB, &QCheckBox::toggled, this, &CollectionExpiryPage::slotUpdateControls);
    daysBox->addWidget(expireReadMailCB, 0, 0, Qt::AlignLeft);

    expireReadMailSB = new KPluralHandlingSpinBox;
    expireReadMailSB->setMaximum(999999);
    expireReadMailSB->setValue(30);
    expireReadMailSB->setSuffix(ki18ncp("Expire messages after %1", " day", " days"));
    daysBox->addWidget(expireReadMailSB, 0, 1);
Laurent Montel's avatar
Laurent Montel committed
76
    connect(expireReadMailSB, QOverload<int>::of(&KPluralHandlingSpinBox::valueChanged), this, &CollectionExpiryPage::slotChanged);
77 78 79 80 81 82 83 84 85 86 87

    expireUnreadMailCB = new QCheckBox;
    expireUnreadMailCB->setText(i18n("Expire unread messages after"));
    connect(expireUnreadMailCB, &QCheckBox::toggled, this, &CollectionExpiryPage::slotUpdateControls);
    daysBox->addWidget(expireUnreadMailCB, 1, 0, Qt::AlignLeft);

    expireUnreadMailSB = new KPluralHandlingSpinBox;
    expireUnreadMailSB->setMaximum(99999);
    expireUnreadMailSB->setValue(30);
    expireUnreadMailSB->setSuffix(ki18ncp("Expire messages after %1", " day", " days"));
    daysBox->addWidget(expireUnreadMailSB, 1, 1);
Laurent Montel's avatar
Laurent Montel committed
88
    connect(expireUnreadMailSB, QOverload<int>::of(&KPluralHandlingSpinBox::valueChanged), this, &CollectionExpiryPage::slotChanged);
89 90 91 92 93 94

    daysBox->setColumnStretch(3, 1);
    globalVBox->addLayout(daysBox);

    globalVBox->addSpacing(30);

Laurent Montel's avatar
Laurent Montel committed
95
    QGroupBox *actionsGroup = new QGroupBox(this);
Laurent Montel's avatar
Laurent Montel committed
96
    actionsGroup->setFlat(true); // for mutual exclusion of the radio buttons
97 98

    QHBoxLayout *moveToHBox = new QHBoxLayout();
99
    moveToHBox->setContentsMargins(0, 0, 0, 0);
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
    moveToHBox->setSpacing(6);

    moveToRB = new QRadioButton(actionsGroup);
    moveToRB->setText(i18n("Move expired messages to:"));
    connect(moveToRB, &QRadioButton::toggled, this, &CollectionExpiryPage::slotUpdateControls);
    moveToHBox->addWidget(moveToRB);

    folderSelector = new FolderRequester(this);
    folderSelector->setMustBeReadWrite(true);
    folderSelector->setShowOutbox(false);
    moveToHBox->addWidget(folderSelector);
    globalVBox->addLayout(moveToHBox);
    connect(folderSelector, &FolderRequester::folderChanged, this, &CollectionExpiryPage::slotChanged);

    deletePermanentlyRB = new QRadioButton(actionsGroup);
    deletePermanentlyRB->setText(i18n("Delete expired messages permanently"));
    connect(deletePermanentlyRB, &QRadioButton::toggled, this, &CollectionExpiryPage::slotUpdateControls);

    globalVBox->addWidget(deletePermanentlyRB);

    globalVBox->addSpacing(30);

    expireNowPB = new QPushButton(i18n("Save Settings and Expire Now"), this);
    connect(expireNowPB, &QPushButton::clicked, this, &CollectionExpiryPage::slotSaveAndExpire);
    globalVBox->addWidget(expireNowPB, 0, Qt::AlignRight);

    globalVBox->addStretch(100);   // eat all superfluous space
}

void CollectionExpiryPage::load(const Akonadi::Collection &collection)
{
    mCollection = collection;
    init();

134 135 136 137 138 139 140
    const MailCommon::ExpireCollectionAttribute *attr = collection.attribute<MailCommon::ExpireCollectionAttribute>();
    if (attr) {
        // Load the values from the folder
        bool expiryGloballyOn = attr->isAutoExpire();
        int daysToExpireRead, daysToExpireUnread;
        attr->daysToExpire(daysToExpireUnread, daysToExpireRead);
        if (expiryGloballyOn
Laurent Montel's avatar
Laurent Montel committed
141 142
            && attr->readExpireUnits() != ExpireCollectionAttribute::ExpireNever
            && daysToExpireRead >= 0) {
143 144 145 146
            expireReadMailCB->setChecked(true);
            expireReadMailSB->setValue(daysToExpireRead);
        }
        if (expiryGloballyOn
Laurent Montel's avatar
Laurent Montel committed
147 148
            && attr->unreadExpireUnits() != ExpireCollectionAttribute::ExpireNever
            && daysToExpireUnread >= 0) {
149 150 151
            expireUnreadMailCB->setChecked(true);
            expireUnreadMailSB->setValue(daysToExpireUnread);
        }
152

153 154 155 156
        if (attr->expireAction() == ExpireCollectionAttribute::ExpireDelete) {
            deletePermanentlyRB->setChecked(true);
        } else {
            moveToRB->setChecked(true);
157 158
        }

159 160 161 162 163 164 165 166 167
        Akonadi::Collection::Id destFolderID = attr->expireToFolderId();
        if (destFolderID > 0) {
            Akonadi::Collection destFolder = Kernel::self()->collectionFromId(destFolderID);
            if (destFolder.isValid()) {
                folderSelector->setCollection(destFolder);
            }
        }
    } else {
        deletePermanentlyRB->setChecked(true);
168 169 170 171 172 173 174 175 176 177 178 179
    }
    slotUpdateControls();
    mChanged = false;
}

void CollectionExpiryPage::save(Akonadi::Collection &collection)
{
    if (mChanged) {
        saveAndExpire(collection, false, true);
    }
}

180
void CollectionExpiryPage::saveAndExpire(Akonadi::Collection &collection, bool saveSettings, bool expireNow)
181 182 183 184 185 186 187 188 189 190
{
    bool enableGlobally = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
    const Akonadi::Collection expireToFolder = folderSelector->collection();
    if (enableGlobally && moveToRB->isChecked() && !expireToFolder.isValid()) {
        KMessageBox::error(this, i18n("Please select a folder to expire messages into.\nIf this is not done, expired messages will be permanently deleted."),
                           i18n("No Folder Selected"));
        deletePermanentlyRB->setChecked(true);
        expireNow = false;                                // settings are not valid
    }

Laurent Montel's avatar
Laurent Montel committed
191
    MailCommon::ExpireCollectionAttribute *attribute = nullptr;
192 193 194 195 196 197 198 199 200 201 202 203
    if (expireToFolder.isValid() && moveToRB->isChecked()) {
        if (expireToFolder.id() == collection.id()) {
            KMessageBox::error(this, i18n("Please select a different folder than the current folder to expire messages into.\nIf this is not done, expired messages will be permanently deleted."),
                               i18n("Wrong Folder Selected"));
            deletePermanentlyRB->setChecked(true);
            expireNow = false;                                // settings are not valid
        } else {
            attribute = collection.attribute<MailCommon::ExpireCollectionAttribute>(Akonadi::Collection::AddIfMissing);
            attribute->setExpireToFolderId(expireToFolder.id());
        }
    }
    if (!attribute) {
Laurent Montel's avatar
Laurent Montel committed
204
        attribute = collection.attribute<MailCommon::ExpireCollectionAttribute>(Akonadi::Collection::AddIfMissing);
205 206 207 208 209 210
    }

    attribute->setAutoExpire(enableGlobally);
    // we always write out days now
    attribute->setReadExpireAge(expireReadMailSB->value());
    attribute->setUnreadExpireAge(expireUnreadMailSB->value());
Laurent Montel's avatar
Laurent Montel committed
211 212 213 214
    attribute->setReadExpireUnits(expireReadMailCB->isChecked() ? MailCommon::ExpireCollectionAttribute::ExpireDays
                                  : MailCommon::ExpireCollectionAttribute::ExpireNever);
    attribute->setUnreadExpireUnits(expireUnreadMailCB->isChecked() ? MailCommon::ExpireCollectionAttribute::ExpireDays
                                    : MailCommon::ExpireCollectionAttribute::ExpireNever);
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269

    if (deletePermanentlyRB->isChecked()) {
        attribute->setExpireAction(ExpireCollectionAttribute::ExpireDelete);
    } else {
        attribute->setExpireAction(ExpireCollectionAttribute::ExpireMove);
    }
    if (saveSettings) {
        Akonadi::CollectionModifyJob *job = new Akonadi::CollectionModifyJob(collection, this);
        job->setProperty("expireNow", expireNow);
        connect(job, &Akonadi::CollectionModifyJob::result, this, &CollectionExpiryPage::slotCollectionModified);
    } else {
        if (expireNow) {
            MailCommon::Util::expireOldMessages(collection, true /*immediate*/);
        }
    }
    mChanged = false;
}

void CollectionExpiryPage::slotSaveAndExpire()
{
    saveAndExpire(mCollection, true, true);                          // save and start expire job
}

void CollectionExpiryPage::slotCollectionModified(KJob *job)
{
    if (job->error()) {
        qCDebug(MAILCOMMON_LOG) << " Error when we modified collection";
        return;
    }

    // trigger immediate expiry if there is something to do
    if (job->property("expireNow").toBool()) {
        MailCommon::Util::expireOldMessages(mCollection, true /*immediate*/);
    }
}

void CollectionExpiryPage::slotUpdateControls()
{
    const bool showExpiryActions = expireReadMailCB->isChecked() || expireUnreadMailCB->isChecked();
    moveToRB->setEnabled(showExpiryActions);
    folderSelector->setEnabled(showExpiryActions && moveToRB->isChecked());
    deletePermanentlyRB->setEnabled(showExpiryActions);

    expireReadMailSB->setEnabled(expireReadMailCB->isChecked());
    expireUnreadMailSB->setEnabled(expireUnreadMailCB->isChecked());

    expireNowPB->setEnabled(showExpiryActions);

    mChanged = true;
}

void CollectionExpiryPage::slotChanged()
{
    mChanged = true;
}