Incidenceeditor

resourcemodel.cpp
1/*
2 * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 *
6 */
7#include "resourcemodel.h"
8#include "ldaputils.h"
9
10#include <KEmailAddress>
11#include <QDebug>
12
13using namespace IncidenceEditorNG;
14
15ResourceModel::ResourceModel(const QStringList &headers, QObject *parent)
16 : QAbstractItemModel(parent)
17{
18 this->mHeaders = headers;
19 mRootItem = ResourceItem::Ptr(new ResourceItem(KLDAPCore::LdapDN(), headers, KLDAPCore::LdapClient(0)));
20 const QStringList attrs = QStringList() << KLDAPCore::LdapClientSearch::defaultAttributes() << QStringLiteral("uniqueMember");
21 mLdapSearchCollections = new KLDAPCore::LdapClientSearch(attrs, this);
22 mLdapSearch = new KLDAPCore::LdapClientSearch(headers, this);
23
24 mLdapSearchCollections->setFilter(
25 QStringLiteral("&(ou=Resources,*)(objectClass=kolabGroupOfUniqueNames)(objectclass=groupofurls)(!(objectclass=nstombstone))(mail=*)"
26 "(cn=%1)"));
27 mLdapSearch->setFilter(
28 QStringLiteral("&(objectClass=kolabSharedFolder)(kolabFolderType=event)(mail=*)"
29 "(|(cn=%1)(description=%1)(kolabDescAttribute=%1))"));
30
31 connect(mLdapSearchCollections,
32 qOverload<const KLDAPCore::LdapResultObject::List &>(&KLDAPCore::LdapClientSearch ::searchData),
33 this,
34 &ResourceModel::slotLDAPCollectionData);
35 connect(mLdapSearch,
36 qOverload<const KLDAPCore::LdapResultObject::List &>(&KLDAPCore::LdapClientSearch::searchData),
37 this,
38 &ResourceModel::slotLDAPSearchData);
39
40 mLdapSearchCollections->startSearch(QStringLiteral("*"));
41}
42
43ResourceModel::~ResourceModel() = default;
44
45int ResourceModel::columnCount(const QModelIndex & /* parent */) const
46{
47 return mRootItem->columnCount();
48}
49
50QVariant ResourceModel::data(const QModelIndex &index, int role) const
51{
52 if (!index.isValid()) {
53 return {};
54 }
55
56 if (role == Qt::EditRole || role == Qt::DisplayRole) {
57 return getItem(index)->data(index.column());
58 } else if (role == Resource) {
59 ResourceItem *p = getItem(parent(index));
60 return QVariant::fromValue(p->child(index.row()));
61 } else if (role == FullName) {
62 ResourceItem *item = getItem(index);
63 return KEmailAddress::normalizedAddress(item->data(QStringLiteral("cn")).toString(), item->data(QStringLiteral("mail")).toString());
64 }
65
66 return {};
67}
68
69Qt::ItemFlags ResourceModel::flags(const QModelIndex &index) const
70{
71 if (!index.isValid()) {
72 return Qt::NoItemFlags;
73 }
74
76}
77
78ResourceItem *ResourceModel::getItem(const QModelIndex &index) const
79{
80 if (index.isValid()) {
81 auto item = static_cast<ResourceItem *>(index.internalPointer());
82 if (item) {
83 return item;
84 }
85 }
86 return mRootItem.data();
87}
88
89QVariant ResourceModel::headerData(int section, Qt::Orientation orientation, int role) const
90{
91 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
92 return translateLDAPAttributeForDisplay(mRootItem->data(section).toString());
93 }
94
95 return {};
96}
97
98QModelIndex ResourceModel::index(int row, int column, const QModelIndex &parent) const
99{
100 ResourceItem *parentItem = getItem(parent);
101
102 ResourceItem::Ptr childItem = parentItem->child(row);
103 if (row < parentItem->childCount() && childItem) {
104 return createIndex(row, column, childItem.data());
105 } else {
106 return {};
107 }
108}
109
111{
112 if (!index.isValid()) {
113 return {};
114 }
115 ResourceItem *childItem = getItem(index);
116 ResourceItem::Ptr parentItem = childItem->parent();
117
118 if (parentItem == mRootItem) {
119 return {};
120 }
121
122 return createIndex(parentItem->childNumber(), index.column(), parentItem.data());
123}
124
125bool ResourceModel::removeRows(int position, int rows, const QModelIndex &parent)
126{
127 ResourceItem *parentItem = getItem(parent);
128
129 beginRemoveRows(parent, position, position + rows - 1);
130 bool success = parentItem->removeChildren(position, rows);
132
133 return success;
134}
135
136int ResourceModel::rowCount(const QModelIndex &parent) const
137{
138 ResourceItem *parentItem = getItem(parent);
139
140 return parentItem->childCount();
141}
142
143void ResourceModel::startSearch(const QString &query)
144{
145 mSearchString = query;
146
147 if (mFoundCollection) {
148 startSearch();
149 }
150}
151
152void ResourceModel::startSearch()
153{
154 // Delete all resources -> only collection elements are shown
155 for (int i = 0; i < mRootItem->childCount(); ++i) {
156 if (mLdapCollections.contains(mRootItem->child(i))) {
157 QModelIndex parentIndex = index(i, 0, QModelIndex());
158 beginRemoveRows(parentIndex, 0, mRootItem->child(i)->childCount() - 1);
159 (void)mRootItem->child(i)->removeChildren(0, mRootItem->child(i)->childCount());
161 } else {
163 (void)mRootItem->removeChildren(i, 1);
165 }
166 }
167
168 if (mSearchString.isEmpty()) {
169 mLdapSearch->startSearch(QStringLiteral("*"));
170 } else {
171 mLdapSearch->startSearch(QLatin1Char('*') + mSearchString + QLatin1Char('*'));
172 }
173}
174
175void ResourceModel::slotLDAPCollectionData(const KLDAPCore::LdapResultObject::List &results)
176{
178
179 mFoundCollection = true;
180 mLdapCollectionsMap.clear();
181 mLdapCollections.clear();
182
183 // qDebug() << "Found ldapCollections";
184
185 for (const KLDAPCore::LdapResultObject &result : std::as_const(results)) {
186 ResourceItem::Ptr item(new ResourceItem(result.object.dn(), mHeaders, *result.client, mRootItem));
187 item->setLdapObject(result.object);
188
189 (void)mRootItem->insertChild(mRootItem->childCount(), item);
190 mLdapCollections.insert(item);
191
192 // Resources in a collection add this link into ldapCollectionsMap
193 const auto members = result.object.attributes()[QStringLiteral("uniqueMember")];
194 for (const QByteArray &member : members) {
195 mLdapCollectionsMap.insert(QString::fromLatin1(member), item);
196 }
197 }
198
200
201 startSearch();
202}
203
204void ResourceModel::slotLDAPSearchData(const KLDAPCore::LdapResultObject::List &results)
205{
206 for (const KLDAPCore::LdapResultObject &result : std::as_const(results)) {
207 // Add the found items to all collections, where it is member
208 QList<ResourceItem::Ptr> parents = mLdapCollectionsMap.values(result.object.dn().toString());
209 if (parents.isEmpty()) {
210 parents << mRootItem;
211 }
212
213 for (const ResourceItem::Ptr &parent : std::as_const(parents)) {
214 ResourceItem::Ptr item(new ResourceItem(result.object.dn(), mHeaders, *result.client, parent));
215 item->setLdapObject(result.object);
216
217 QModelIndex parentIndex;
218 if (parent != mRootItem) {
219 parentIndex = index(parent->childNumber(), 0, parentIndex);
220 }
221 beginInsertRows(parentIndex, parent->childCount(), parent->childCount());
222 (void)parent->insertChild(parent->childCount(), item);
224 }
225 }
226}
227
228#include "moc_resourcemodel.cpp"
void searchData(const KLDAPCore::LdapResult::List &results)
void startSearch(const QString &query)
KCODECS_EXPORT QString normalizedAddress(const QString &displayName, const QString &addrSpec, const QString &comment=QString())
char * toString(const EngineQuery &query)
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
void beginInsertRows(const QModelIndex &parent, int first, int last)
void beginRemoveRows(const QModelIndex &parent, int first, int last)
QModelIndex createIndex(int row, int column, const void *ptr) const const
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
bool isEmpty() const const
int column() const const
void * internalPointer() const const
bool isValid() const const
int row() const const
Q_EMITQ_EMIT
QObject * parent() const const
T * data() const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
EditRole
typedef ItemFlags
Orientation
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:16:44 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.