Warning, file /pim/mailcommon/src/collectionpage/collectionexpirywidget.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "collectionexpirywidget.h" 0008 #include "attributes/expirecollectionattribute.h" 0009 #include "collectionexpiryjob.h" 0010 #include "folder/foldersettings.h" 0011 #include "folderrequester.h" 0012 #include "kernel/mailkernel.h" 0013 #include "util/mailutil.h" 0014 0015 #include <Akonadi/CollectionModifyJob> 0016 0017 #include <KMessageBox> 0018 #include <KPluralHandlingSpinBox> 0019 #include <QCheckBox> 0020 #include <QFormLayout> 0021 #include <QGroupBox> 0022 #include <QHBoxLayout> 0023 #include <QPushButton> 0024 #include <QRadioButton> 0025 0026 using namespace MailCommon; 0027 0028 class DaysSpinBox : public KPluralHandlingSpinBox 0029 { 0030 public: 0031 DaysSpinBox(QWidget *parent) 0032 : KPluralHandlingSpinBox(parent) 0033 { 0034 setMaximum(999999); 0035 setSuffix(ki18ncp("Expire messages after %1", " day", " days")); 0036 setSpecialValueText(i18n("Never")); 0037 } 0038 0039 [[nodiscard]] QString textFromValue(int value) const override 0040 { 0041 if (value == 0) { 0042 return i18n("Never"); 0043 } 0044 return KPluralHandlingSpinBox::textFromValue(value); 0045 } 0046 0047 [[nodiscard]] int valueFromText(const QString &text) const override 0048 { 0049 return KPluralHandlingSpinBox::valueFromText(text); 0050 } 0051 0052 QValidator::State validate(QString &text, int &pos) const override 0053 { 0054 if (text == i18n("Never")) { 0055 return QValidator::Acceptable; 0056 } 0057 return KPluralHandlingSpinBox::validate(text, pos); 0058 } 0059 }; 0060 0061 CollectionExpiryWidget::CollectionExpiryWidget(QWidget *parent) 0062 : QWidget(parent) 0063 , mExpireReadMailSB(new DaysSpinBox(this)) 0064 , mExpireUnreadMailSB(new DaysSpinBox(this)) 0065 , mFolderSelector(new FolderRequester(this)) 0066 , mExpireNowPB(new QPushButton(i18n("Save Settings and Expire Now"), this)) 0067 , mExpireMailWithInvalidDateCB(new QCheckBox(i18n("Expire messages with invalid date"), this)) 0068 { 0069 auto formLayout = new QFormLayout(this); 0070 formLayout->setContentsMargins({}); 0071 0072 connect(mExpireReadMailSB, &KPluralHandlingSpinBox::valueChanged, this, &CollectionExpiryWidget::slotChanged); 0073 formLayout->addRow(i18n("Expire read messages after:"), mExpireReadMailSB); 0074 0075 connect(mExpireUnreadMailSB, &KPluralHandlingSpinBox::valueChanged, this, &CollectionExpiryWidget::slotChanged); 0076 formLayout->addRow(i18n("Expire unread messages after:"), mExpireUnreadMailSB); 0077 0078 connect(mExpireMailWithInvalidDateCB, &QCheckBox::toggled, this, &CollectionExpiryWidget::slotChanged); 0079 formLayout->addRow(QString(), mExpireMailWithInvalidDateCB); 0080 0081 auto actionsGroup = new QGroupBox(this); 0082 actionsGroup->setFlat(true); // for mutual exclusion of the radio buttons 0083 formLayout->addRow(actionsGroup); 0084 0085 auto moveToHBox = new QHBoxLayout(); 0086 moveToHBox->setContentsMargins({}); 0087 moveToHBox->setSpacing(6); 0088 0089 mMoveToRB = new QRadioButton(actionsGroup); 0090 mMoveToRB->setText(i18n("Move expired messages to:")); 0091 connect(mMoveToRB, &QRadioButton::toggled, this, &CollectionExpiryWidget::slotChanged); 0092 moveToHBox->addWidget(mMoveToRB); 0093 0094 mFolderSelector->setMustBeReadWrite(true); 0095 mFolderSelector->setShowOutbox(false); 0096 moveToHBox->addWidget(mFolderSelector); 0097 formLayout->addRow(QString(), moveToHBox); 0098 connect(mFolderSelector, &FolderRequester::folderChanged, this, &CollectionExpiryWidget::slotChanged); 0099 0100 mDeletePermanentlyRB = new QRadioButton(actionsGroup); 0101 mDeletePermanentlyRB->setText(i18n("Delete expired messages permanently")); 0102 connect(mDeletePermanentlyRB, &QRadioButton::toggled, this, &CollectionExpiryWidget::slotChanged); 0103 0104 formLayout->addRow(QString(), mDeletePermanentlyRB); 0105 0106 connect(mExpireNowPB, &QPushButton::clicked, this, &CollectionExpiryWidget::saveAndExpireRequested); 0107 formLayout->addRow(QString(), mExpireNowPB); 0108 0109 mDeletePermanentlyRB->setChecked(true); 0110 slotChanged(); 0111 } 0112 0113 CollectionExpiryWidget::~CollectionExpiryWidget() = default; 0114 0115 void CollectionExpiryWidget::hideExpireNowButton() 0116 { 0117 mExpireNowPB->setVisible(false); 0118 } 0119 0120 void CollectionExpiryWidget::slotChanged() 0121 { 0122 const bool showExpiryActions = mExpireReadMailSB->value() != 0 || mExpireUnreadMailSB->value() != 0; 0123 mMoveToRB->setEnabled(showExpiryActions); 0124 mFolderSelector->setEnabled(showExpiryActions && mMoveToRB->isChecked()); 0125 mDeletePermanentlyRB->setEnabled(showExpiryActions); 0126 mExpireNowPB->setEnabled(showExpiryActions); 0127 0128 Q_EMIT configChanged(); 0129 } 0130 0131 void CollectionExpiryWidget::load(const MailCommon::CollectionExpirySettings &settings) 0132 { 0133 if (settings.isValid()) { 0134 bool expiryGloballyOn = settings.expiryGloballyOn; 0135 if (expiryGloballyOn && settings.mReadExpireUnits != ExpireCollectionAttribute::ExpireNever && settings.daysToExpireRead >= 0) { 0136 mExpireReadMailSB->setValue(settings.daysToExpireRead); 0137 } else { 0138 mExpireReadMailSB->setValue(0); 0139 } 0140 if (expiryGloballyOn && settings.mUnreadExpireUnits != ExpireCollectionAttribute::ExpireNever && settings.daysToExpireUnread >= 0) { 0141 mExpireUnreadMailSB->setValue(settings.daysToExpireUnread); 0142 } else { 0143 mExpireUnreadMailSB->setValue(0); 0144 } 0145 0146 if (settings.mExpireAction == ExpireCollectionAttribute::ExpireDelete) { 0147 mDeletePermanentlyRB->setChecked(true); 0148 } else { 0149 mMoveToRB->setChecked(true); 0150 } 0151 0152 mExpireMailWithInvalidDateCB->setChecked(settings.expiryMessagesWithInvalidDate); 0153 Akonadi::Collection::Id destFolderID = settings.mExpireToFolderId; 0154 if (destFolderID > 0) { 0155 Akonadi::Collection destFolder = Kernel::self()->collectionFromId(destFolderID); 0156 if (destFolder.isValid()) { 0157 mFolderSelector->setCollection(destFolder); 0158 } 0159 } 0160 } else { 0161 mDeletePermanentlyRB->setChecked(true); 0162 } 0163 slotChanged(); 0164 } 0165 0166 bool CollectionExpiryWidget::validateExpireFolder(bool expireNow) 0167 { 0168 const bool enableGlobally = mExpireReadMailSB->value() != 0 || mExpireUnreadMailSB->value() != 0; 0169 const Akonadi::Collection expireToFolder = mFolderSelector->collection(); 0170 if (enableGlobally && mMoveToRB->isChecked() && !expireToFolder.isValid()) { 0171 KMessageBox::error(this, 0172 i18n("Please select a folder to expire messages into.\nIf this is not done, expired messages will be permanently deleted."), 0173 i18n("No Folder Selected")); 0174 mDeletePermanentlyRB->setChecked(true); 0175 expireNow = false; // settings are not valid 0176 } 0177 return expireNow; 0178 } 0179 0180 MailCommon::ExpireCollectionAttribute *CollectionExpiryWidget::assignFolderAttribute(Akonadi::Collection &collection, bool &expireNow) 0181 { 0182 const Akonadi::Collection expireToFolder = mFolderSelector->collection(); 0183 MailCommon::ExpireCollectionAttribute *attribute = nullptr; 0184 if (expireToFolder.isValid() && mMoveToRB->isChecked()) { 0185 if (expireToFolder.id() == collection.id()) { 0186 KMessageBox::error(this, 0187 i18n("Please select a different folder than the current folder to expire messages into.\nIf this is not done, expired messages " 0188 "will be permanently deleted."), 0189 i18n("Wrong Folder Selected")); 0190 mDeletePermanentlyRB->setChecked(true); 0191 expireNow = false; // settings are not valid 0192 } else { 0193 attribute = collection.attribute<MailCommon::ExpireCollectionAttribute>(Akonadi::Collection::AddIfMissing); 0194 attribute->setExpireToFolderId(expireToFolder.id()); 0195 } 0196 } 0197 if (!attribute) { 0198 attribute = collection.attribute<MailCommon::ExpireCollectionAttribute>(Akonadi::Collection::AddIfMissing); 0199 } 0200 return attribute; 0201 } 0202 0203 CollectionExpirySettings CollectionExpiryWidget::settings() const 0204 { 0205 CollectionExpirySettings settings; 0206 settings.expiryGloballyOn = mExpireReadMailSB->value() != 0 || mExpireUnreadMailSB->value() != 0; 0207 settings.expiryMessagesWithInvalidDate = mExpireMailWithInvalidDateCB->isChecked(); 0208 // we always write out days now 0209 settings.daysToExpireRead = mExpireReadMailSB->value(); 0210 settings.daysToExpireUnread = mExpireUnreadMailSB->value(); 0211 settings.mReadExpireUnits = 0212 mExpireReadMailSB->value() != 0 ? MailCommon::ExpireCollectionAttribute::ExpireDays : MailCommon::ExpireCollectionAttribute::ExpireNever; 0213 settings.mUnreadExpireUnits = 0214 mExpireUnreadMailSB->value() != 0 ? MailCommon::ExpireCollectionAttribute::ExpireDays : MailCommon::ExpireCollectionAttribute::ExpireNever; 0215 0216 if (mDeletePermanentlyRB->isChecked()) { 0217 settings.mExpireAction = ExpireCollectionAttribute::ExpireDelete; 0218 } else { 0219 settings.mExpireAction = ExpireCollectionAttribute::ExpireMove; 0220 } 0221 return settings; 0222 } 0223 0224 void CollectionExpiryWidget::save(const CollectionExpirySettings &collectionExpirySettings, Akonadi::Collection &collection, bool saveSettings, bool expireNow) 0225 { 0226 expireNow = validateExpireFolder(expireNow); 0227 MailCommon::ExpireCollectionAttribute *attribute = assignFolderAttribute(collection, expireNow); 0228 attribute->setAutoExpire(collectionExpirySettings.expiryGloballyOn); 0229 // we always write out days now 0230 attribute->setReadExpireAge(collectionExpirySettings.daysToExpireRead); 0231 attribute->setUnreadExpireAge(collectionExpirySettings.daysToExpireUnread); 0232 attribute->setReadExpireUnits(collectionExpirySettings.mReadExpireUnits); 0233 attribute->setUnreadExpireUnits(collectionExpirySettings.mUnreadExpireUnits); 0234 attribute->setExpireAction(collectionExpirySettings.mExpireAction); 0235 0236 if (saveSettings) { 0237 auto job = new CollectionExpiryJob; 0238 job->setExpireNow(expireNow); 0239 job->setCollection(collection); 0240 job->start(); 0241 } else { 0242 if (expireNow) { 0243 MailCommon::Util::expireOldMessages(collection, true /*immediate*/); 0244 } 0245 } 0246 Q_EMIT configChanged(false); 0247 } 0248 0249 void CollectionExpiryWidget::save(Akonadi::Collection &collection, bool saveSettings, bool expireNow) 0250 { 0251 const CollectionExpirySettings collectionExpirySettings = settings(); 0252 save(collectionExpirySettings, collection, saveSettings, expireNow); 0253 } 0254 0255 bool CollectionExpiryWidget::canHandle(const Akonadi::Collection &col) 0256 { 0257 QSharedPointer<FolderSettings> fd = FolderSettings::forCollection(col, false); 0258 return fd->canDeleteMessages() && !fd->isStructural() && !MailCommon::Util::isVirtualCollection(col); 0259 } 0260 0261 bool CollectionExpirySettings::isValid() const 0262 { 0263 const bool valid = daysToExpireRead != -1 || daysToExpireUnread != -1 || mUnreadExpireUnits != ExpireCollectionAttribute::ExpireNever 0264 || mReadExpireUnits != ExpireCollectionAttribute::ExpireNever || mExpireAction != ExpireCollectionAttribute::ExpireDelete || mExpireToFolderId != -1; 0265 return valid; 0266 } 0267 0268 QDebug operator<<(QDebug d, const CollectionExpirySettings &t) 0269 { 0270 d << " expiryGloballyOn " << t.expiryGloballyOn; 0271 d << " expiryMessagesWithInvalidDate " << t.expiryMessagesWithInvalidDate; 0272 d << " daysToExpireRead " << t.daysToExpireRead; 0273 d << " daysToExpireUnread " << t.daysToExpireUnread; 0274 d << " mUnreadExpireUnits " << t.mUnreadExpireUnits; 0275 d << " mReadExpireUnits " << t.mReadExpireUnits; 0276 d << " mExpireAction " << t.mExpireAction; 0277 d << " mExpireToFolderId " << t.mExpireToFolderId; 0278 return d; 0279 } 0280 0281 #include "moc_collectionexpirywidget.cpp"