File indexing completed on 2024-05-12 05:11:10
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com> 0003 SPDX-FileCopyrightText: 2010 Andras Mantia <andras@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "emptytrashcommand.h" 0009 #include "imapsettings.h" 0010 #include "specialmailcollections.h" 0011 #include "util_p.h" 0012 0013 #include "akonadi_mime_debug.h" 0014 #include <KLocalizedString> 0015 #include <KMessageBox> 0016 0017 #include <Akonadi/AgentManager> 0018 #include <Akonadi/EntityTreeModel> 0019 #include <Akonadi/ItemDeleteJob> 0020 #include <Akonadi/ItemFetchJob> 0021 #include <KMime/KMimeMessage> 0022 using namespace Akonadi; 0023 EmptyTrashCommand::EmptyTrashCommand(const QAbstractItemModel *model, QObject *parent) 0024 : CommandBase(parent) 0025 , mModel(model) 0026 , the_trashCollectionFolder(-1) 0027 { 0028 } 0029 0030 EmptyTrashCommand::EmptyTrashCommand(const Akonadi::Collection &folder, QObject *parent) 0031 : CommandBase(parent) 0032 , mModel(nullptr) 0033 , the_trashCollectionFolder(-1) 0034 , mFolder(folder) 0035 { 0036 } 0037 0038 void EmptyTrashCommand::execute() 0039 { 0040 if (!mFolder.isValid() && !mModel) { 0041 emitResult(Failed); 0042 return; 0043 } 0044 0045 if (!mFolder.isValid()) { // expunge all 0046 const QString title = i18n("Empty Trash"); 0047 const QString text = i18n("Are you sure you want to empty the trash folders of all accounts?"); 0048 if (KMessageBox::warningContinueCancel(nullptr, 0049 text, 0050 title, 0051 KStandardGuiItem::cont(), 0052 KStandardGuiItem::cancel(), 0053 QStringLiteral("confirm_empty_trash")) 0054 != KMessageBox::Continue) { 0055 emitResult(OK); 0056 return; 0057 } 0058 Akonadi::Collection trash = trashCollectionFolder(); 0059 QList<Akonadi::Collection> trashFolder; 0060 trashFolder << trash; 0061 0062 const Akonadi::AgentInstance::List lst = agentInstances(); 0063 for (const Akonadi::AgentInstance &type : lst) { 0064 if (type.identifier().contains(IMAP_RESOURCE_IDENTIFIER)) { 0065 if (type.status() == Akonadi::AgentInstance::Broken) { 0066 continue; 0067 } 0068 QScopedPointer<OrgKdeAkonadiImapSettingsInterface> iface{Util::createImapSettingsInterface(type.identifier())}; 0069 if (iface->isValid()) { 0070 const int trashImap = iface->trashCollection(); 0071 if (trashImap != trash.id()) { 0072 trashFolder << Akonadi::Collection(trashImap); 0073 } 0074 } 0075 } 0076 } 0077 mNumberOfTrashToEmpty = trashFolder.count(); 0078 for (int i = 0; i < mNumberOfTrashToEmpty; ++i) { 0079 expunge(trashFolder.at(i)); 0080 } 0081 } else { 0082 if (folderIsTrash(mFolder)) { 0083 mNumberOfTrashToEmpty++; 0084 expunge(mFolder); 0085 } else { 0086 emitResult(OK); 0087 } 0088 } 0089 } 0090 0091 void EmptyTrashCommand::expunge(const Akonadi::Collection &col) 0092 { 0093 if (col.isValid()) { 0094 auto jobDelete = new Akonadi::ItemDeleteJob(col, this); 0095 connect(jobDelete, &Akonadi::ItemDeleteJob::result, this, [this, jobDelete]() { 0096 if (jobDelete->error()) { 0097 Util::showJobError(jobDelete); 0098 emitResult(Failed); 0099 } 0100 emitResult(OK); 0101 }); 0102 } else { 0103 qCWarning(AKONADIMIME_LOG) << " Try to expunge an invalid collection :" << col; 0104 emitResult(Failed); 0105 } 0106 } 0107 0108 Akonadi::AgentInstance::List EmptyTrashCommand::agentInstances() 0109 { 0110 Akonadi::AgentInstance::List relevantInstances; 0111 const auto instances = Akonadi::AgentManager::self()->instances(); 0112 for (const Akonadi::AgentInstance &instance : instances) { 0113 if (instance.type().mimeTypes().contains(KMime::Message::mimeType()) && instance.type().capabilities().contains(QLatin1StringView("Resource")) 0114 && !instance.type().capabilities().contains(QLatin1StringView("Virtual"))) { 0115 relevantInstances << instance; 0116 } 0117 } 0118 return relevantInstances; 0119 } 0120 0121 Akonadi::Collection EmptyTrashCommand::collectionFromId(Collection::Id id) const 0122 { 0123 const QModelIndex idx = Akonadi::EntityTreeModel::modelIndexForCollection(mModel, Akonadi::Collection(id)); 0124 return idx.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 0125 } 0126 0127 Akonadi::Collection EmptyTrashCommand::trashCollectionFolder() 0128 { 0129 if (the_trashCollectionFolder < 0) { 0130 the_trashCollectionFolder = Akonadi::SpecialMailCollections::self()->defaultCollection(Akonadi::SpecialMailCollections::Trash).id(); 0131 } 0132 return collectionFromId(the_trashCollectionFolder); 0133 } 0134 0135 bool EmptyTrashCommand::folderIsTrash(const Akonadi::Collection &col) 0136 { 0137 if (col == Akonadi::SpecialMailCollections::self()->defaultCollection(Akonadi::SpecialMailCollections::Trash)) { 0138 return true; 0139 } 0140 const Akonadi::AgentInstance::List lst = agentInstances(); 0141 for (const Akonadi::AgentInstance &type : lst) { 0142 if (type.status() == Akonadi::AgentInstance::Broken) { 0143 continue; 0144 } 0145 if (type.identifier().contains(IMAP_RESOURCE_IDENTIFIER)) { 0146 QScopedPointer<OrgKdeAkonadiImapSettingsInterface> iface{Util::createImapSettingsInterface(type.identifier())}; 0147 if (iface->isValid()) { 0148 if (iface->trashCollection() == col.id()) { 0149 return true; 0150 } 0151 } 0152 } 0153 } 0154 return false; 0155 } 0156 0157 void EmptyTrashCommand::emitResult(Result value) 0158 { 0159 Q_EMIT result(value); 0160 mNumberOfTrashToEmpty--; 0161 if (mNumberOfTrashToEmpty <= 0) { 0162 deleteLater(); 0163 } 0164 } 0165 0166 #include "moc_emptytrashcommand.cpp"