1 /*
2     SPDX-FileCopyrightText: 2009 Tobias Koenig <tokoe@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "akonadicore_debug.h"
8 #include "asyncselectionhandler_p.h"
9 #include "models/entitytreemodel.h"
10 
11 using namespace Akonadi;
12 
AsyncSelectionHandler(QAbstractItemModel * model,QObject * parent)13 AsyncSelectionHandler::AsyncSelectionHandler(QAbstractItemModel *model, QObject *parent)
14     : QObject(parent)
15     , mModel(model)
16 {
17     Q_ASSERT(mModel);
18 
19     connect(mModel, &QAbstractItemModel::rowsInserted, this, &AsyncSelectionHandler::rowsInserted);
20 }
21 
~AsyncSelectionHandler()22 AsyncSelectionHandler::~AsyncSelectionHandler()
23 {
24 }
25 
scanSubTree(const QModelIndex & index,bool searchForItem)26 bool AsyncSelectionHandler::scanSubTree(const QModelIndex &index, bool searchForItem)
27 {
28     if (searchForItem) {
29         const Item::Id id = index.data(EntityTreeModel::ItemIdRole).toLongLong();
30 
31         if (mItem.id() == id) {
32             Q_EMIT itemAvailable(index);
33             return true;
34         }
35     } else {
36         const Collection::Id id = index.data(EntityTreeModel::CollectionIdRole).toLongLong();
37 
38         if (mCollection.id() == id) {
39             Q_EMIT collectionAvailable(index);
40             return true;
41         }
42     }
43 
44     for (int row = 0; row < mModel->rowCount(index); ++row) {
45         const QModelIndex childIndex = mModel->index(row, 0, index);
46         // This should not normally happen, but if it does we end up in an endless loop
47         if (!childIndex.isValid()) {
48             qCWarning(AKONADICORE_LOG) << "Invalid child detected: " << index.data().toString();
49             Q_ASSERT(false);
50             return false;
51         }
52         if (scanSubTree(childIndex, searchForItem)) {
53             return true;
54         }
55     }
56 
57     return false;
58 }
59 
waitForCollection(const Collection & collection)60 void AsyncSelectionHandler::waitForCollection(const Collection &collection)
61 {
62     mCollection = collection;
63 
64     scanSubTree(QModelIndex(), false);
65 }
66 
waitForItem(const Item & item)67 void AsyncSelectionHandler::waitForItem(const Item &item)
68 {
69     mItem = item;
70 
71     scanSubTree(QModelIndex(), true);
72 }
73 
rowsInserted(const QModelIndex & parent,int start,int end)74 void AsyncSelectionHandler::rowsInserted(const QModelIndex &parent, int start, int end)
75 {
76     for (int i = start; i <= end; ++i) {
77         scanSubTree(mModel->index(i, 0, parent), false);
78         scanSubTree(mModel->index(i, 0, parent), true);
79     }
80 }
81 
82 #include "moc_asyncselectionhandler_p.cpp"
83