Messagelib

searchcollectionindexingwarning.cpp
1 /*
2  * SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
3  *
4  * SPDX-License-Identifier: GPL-2.0-or-later
5  *
6  */
7 
8 #include "searchcollectionindexingwarning.h"
9 #include "messagelist_debug.h"
10 
11 #include <Akonadi/CachePolicy>
12 #include <Akonadi/CollectionFetchJob>
13 #include <Akonadi/CollectionFetchScope>
14 #include <Akonadi/CollectionStatistics>
15 #include <Akonadi/EntityHiddenAttribute>
16 #include <Akonadi/PersistentSearchAttribute>
17 
18 #include <PimCommon/PimUtil>
19 
20 #include <KLocalizedString>
21 
22 #include <AkonadiSearch/PIM/indexeditems.h>
23 
24 using namespace MessageList::Core;
25 
26 SearchCollectionIndexingWarning::SearchCollectionIndexingWarning(QWidget *parent)
27  : KMessageWidget(parent)
28  , mIndexedItems(new Akonadi::Search::PIM::IndexedItems(this))
29 {
30  setVisible(false);
31  setWordWrap(true);
32  setText(
33  i18n("Some of the search folders in this query are still being indexed "
34  "or are excluded from indexing completely. The results below may be incomplete."));
35  setCloseButtonVisible(true);
36  setMessageType(Information);
37 }
38 
39 SearchCollectionIndexingWarning::~SearchCollectionIndexingWarning() = default;
40 
41 Akonadi::CollectionFetchJob *SearchCollectionIndexingWarning::fetchCollections(const Akonadi::Collection::List &cols, bool recursive)
42 {
44  auto fetch = new Akonadi::CollectionFetchJob(cols, type, this);
45  fetch->fetchScope().setAncestorRetrieval(Akonadi::CollectionFetchScope::None);
46  fetch->fetchScope().setContentMimeTypes(QStringList() << Akonadi::Collection::mimeType() << QStringLiteral("message/rfc822"));
47  fetch->fetchScope().setIncludeStatistics(true);
48  return fetch;
49 }
50 
51 void SearchCollectionIndexingWarning::setCollection(const Akonadi::Collection &collection)
52 {
53  if (collection == mCollection) {
54  return;
55  }
56 
57  animatedHide();
58 
59  mCollection = collection;
60  mCollections.clear();
61 
62  // Not a search collection?
64  return;
65  }
66 
67  const auto attr = collection.attribute<Akonadi::PersistentSearchAttribute>();
69  const QVector<qint64> queryCols = attr->queryCollections();
70  cols.reserve(queryCols.count());
71  for (qint64 col : queryCols) {
72  cols.push_back(Akonadi::Collection(col));
73  }
74  if (cols.isEmpty()) {
75  return;
76  }
77 
78  // First retrieve the top-level collections
79  Akonadi::CollectionFetchJob *fetch = fetchCollections(cols, false);
80  fetch->setProperty("recursiveQuery", attr->isRecursive());
81  connect(fetch, &Akonadi::CollectionFetchJob::finished, this, &SearchCollectionIndexingWarning::queryRootCollectionFetchFinished);
82 }
83 
84 void SearchCollectionIndexingWarning::queryRootCollectionFetchFinished(KJob *job)
85 {
86  if (job->error()) {
87  qCWarning(MESSAGELIST_LOG) << job->errorString();
88  return;
89  }
90 
91  // Store the root collections
92  mCollections = qobject_cast<Akonadi::CollectionFetchJob *>(job)->collections();
93 
94  if (job->property("recursiveQuery").toBool()) {
95  // Fetch all descendants, if necessary
96  Akonadi::CollectionFetchJob *fetch = fetchCollections(mCollections, true);
97  connect(fetch, &Akonadi::CollectionFetchJob::finished, this, &SearchCollectionIndexingWarning::queryCollectionFetchFinished);
98  } else {
99  queryIndexerStatus();
100  }
101 }
102 
103 void SearchCollectionIndexingWarning::queryCollectionFetchFinished(KJob *job)
104 {
105  if (job->error()) {
106  qCWarning(MESSAGELIST_LOG) << job->errorString();
107  return;
108  }
109 
110  mCollections += qobject_cast<Akonadi::CollectionFetchJob *>(job)->collections();
111  queryIndexerStatus();
112 }
113 
114 void SearchCollectionIndexingWarning::queryIndexerStatus()
115 {
116  bool allFullyIndexed = true;
117  for (const Akonadi::Collection &col : std::as_const(mCollections)) {
118  if (col.hasAttribute<Akonadi::EntityHiddenAttribute>()) {
119  continue;
120  }
121  if (PimCommon::Util::isImapResource(col.resource()) && !col.cachePolicy().localParts().contains(QLatin1String("RFC822"))) {
122  continue;
123  }
124  const qlonglong result = mIndexedItems->indexedItems(col.id());
125 
126  qCDebug(MESSAGELIST_LOG) << "Collection:" << col.displayName() << "(" << col.id() << "), count:" << col.statistics().count() << ", index:" << result;
127  if (col.statistics().count() != result) {
128  allFullyIndexed = false;
129  break;
130  }
131  }
132  if (!allFullyIndexed) {
133  animatedShow();
134  }
135 }
virtual QString errorString() const
static QString mimeType()
The implementation independent part of the MessageList library.
Definition: aggregation.h:21
PartitionTable::TableType type
QVariant property(const char *name) const const
void finished(KJob *job)
Attribute * attribute(const QByteArray &name)
void reserve(int size)
bool hasAttribute(const QByteArray &name) const
QString i18n(const char *text, const TYPE &arg...)
int count(const T &value) const const
bool toBool() const const
bool setProperty(const char *name, const QVariant &value)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
T qobject_cast(QObject *object)
int error() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Dec 5 2021 23:04:55 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.