File indexing completed on 2024-12-15 04:54:36
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 * 0006 */ 0007 0008 #include "searchcollectionindexingwarning.h" 0009 #include "messagelist_debug.h" 0010 0011 #include <Akonadi/CachePolicy> 0012 #include <Akonadi/CollectionFetchJob> 0013 #include <Akonadi/CollectionFetchScope> 0014 #include <Akonadi/CollectionStatistics> 0015 #include <Akonadi/EntityHiddenAttribute> 0016 #include <Akonadi/PersistentSearchAttribute> 0017 0018 #include <PimCommon/PimUtil> 0019 0020 #include <KLocalizedString> 0021 0022 #include <PIM/indexeditems.h> 0023 0024 using namespace MessageList::Core; 0025 0026 SearchCollectionIndexingWarning::SearchCollectionIndexingWarning(QWidget *parent) 0027 : KMessageWidget(parent) 0028 , mIndexedItems(new Akonadi::Search::PIM::IndexedItems(this)) 0029 { 0030 setVisible(false); 0031 setWordWrap(true); 0032 setText( 0033 i18n("Some of the search folders in this query are still being indexed " 0034 "or are excluded from indexing completely. The results below may be incomplete.")); 0035 setCloseButtonVisible(true); 0036 setMessageType(Information); 0037 } 0038 0039 SearchCollectionIndexingWarning::~SearchCollectionIndexingWarning() = default; 0040 0041 Akonadi::CollectionFetchJob *SearchCollectionIndexingWarning::fetchCollections(const Akonadi::Collection::List &cols, bool recursive) 0042 { 0043 const Akonadi::CollectionFetchJob::Type type = recursive ? Akonadi::CollectionFetchJob::Recursive : Akonadi::CollectionFetchJob::Base; 0044 auto fetch = new Akonadi::CollectionFetchJob(cols, type, this); 0045 fetch->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::None); 0046 fetch->fetchScope().setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType() << QStringLiteral("message/rfc822")); 0047 fetch->fetchScope().setIncludeStatistics(true); 0048 return fetch; 0049 } 0050 0051 void SearchCollectionIndexingWarning::setCollection(const Akonadi::Collection &collection) 0052 { 0053 if (collection == mCollection) { 0054 return; 0055 } 0056 0057 animatedHide(); 0058 0059 mCollection = collection; 0060 mCollections.clear(); 0061 0062 // Not a search collection? 0063 if (!collection.hasAttribute<Akonadi::PersistentSearchAttribute>()) { 0064 return; 0065 } 0066 0067 const auto attr = collection.attribute<Akonadi::PersistentSearchAttribute>(); 0068 Akonadi::Collection::List cols; 0069 const QList<qint64> queryCols = attr->queryCollections(); 0070 cols.reserve(queryCols.count()); 0071 for (qint64 col : queryCols) { 0072 cols.push_back(Akonadi::Collection(col)); 0073 } 0074 if (cols.isEmpty()) { 0075 return; 0076 } 0077 0078 // First retrieve the top-level collections 0079 Akonadi::CollectionFetchJob *fetch = fetchCollections(cols, false); 0080 fetch->setProperty("recursiveQuery", attr->isRecursive()); 0081 connect(fetch, &Akonadi::CollectionFetchJob::finished, this, &SearchCollectionIndexingWarning::queryRootCollectionFetchFinished); 0082 } 0083 0084 void SearchCollectionIndexingWarning::queryRootCollectionFetchFinished(KJob *job) 0085 { 0086 if (job->error()) { 0087 qCWarning(MESSAGELIST_LOG) << job->errorString(); 0088 return; 0089 } 0090 0091 // Store the root collections 0092 mCollections = qobject_cast<Akonadi::CollectionFetchJob *>(job)->collections(); 0093 0094 if (job->property("recursiveQuery").toBool()) { 0095 // Fetch all descendants, if necessary 0096 Akonadi::CollectionFetchJob *fetch = fetchCollections(mCollections, true); 0097 connect(fetch, &Akonadi::CollectionFetchJob::finished, this, &SearchCollectionIndexingWarning::queryCollectionFetchFinished); 0098 } else { 0099 queryIndexerStatus(); 0100 } 0101 } 0102 0103 void SearchCollectionIndexingWarning::queryCollectionFetchFinished(KJob *job) 0104 { 0105 if (job->error()) { 0106 qCWarning(MESSAGELIST_LOG) << job->errorString(); 0107 return; 0108 } 0109 0110 mCollections += qobject_cast<Akonadi::CollectionFetchJob *>(job)->collections(); 0111 queryIndexerStatus(); 0112 } 0113 0114 void SearchCollectionIndexingWarning::queryIndexerStatus() 0115 { 0116 bool allFullyIndexed = true; 0117 for (const Akonadi::Collection &col : std::as_const(mCollections)) { 0118 if (col.hasAttribute<Akonadi::EntityHiddenAttribute>()) { 0119 continue; 0120 } 0121 if (PimCommon::Util::isImapResource(col.resource()) && !col.cachePolicy().localParts().contains(QLatin1StringView("RFC822"))) { 0122 continue; 0123 } 0124 const qlonglong result = mIndexedItems->indexedItems(col.id()); 0125 0126 qCDebug(MESSAGELIST_LOG) << "Collection:" << col.displayName() << "(" << col.id() << "), count:" << col.statistics().count() << ", index:" << result; 0127 if (col.statistics().count() != result) { 0128 allFullyIndexed = false; 0129 break; 0130 } 0131 } 0132 if (!allFullyIndexed) { 0133 animatedShow(); 0134 } 0135 } 0136 0137 #include "moc_searchcollectionindexingwarning.cpp"