File indexing completed on 2024-04-28 05:11:38
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Sandro Knauß <knauss@kolabsys.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 * 0006 */ 0007 #include "resourcemodel.h" 0008 #include "ldaputils.h" 0009 0010 #include <KEmailAddress> 0011 #include <QDebug> 0012 0013 using namespace IncidenceEditorNG; 0014 0015 ResourceModel::ResourceModel(const QStringList &headers, QObject *parent) 0016 : QAbstractItemModel(parent) 0017 { 0018 this->mHeaders = headers; 0019 mRootItem = ResourceItem::Ptr(new ResourceItem(KLDAPCore::LdapDN(), headers, KLDAPWidgets::LdapClient(0))); 0020 const QStringList attrs = QStringList() << KLDAPWidgets::LdapClientSearch::defaultAttributes() << QStringLiteral("uniqueMember"); 0021 mLdapSearchCollections = new KLDAPWidgets::LdapClientSearch(attrs, this); 0022 mLdapSearch = new KLDAPWidgets::LdapClientSearch(headers, this); 0023 0024 mLdapSearchCollections->setFilter( 0025 QStringLiteral("&(ou=Resources,*)(objectClass=kolabGroupOfUniqueNames)(objectclass=groupofurls)(!(objectclass=nstombstone))(mail=*)" 0026 "(cn=%1)")); 0027 mLdapSearch->setFilter( 0028 QStringLiteral("&(objectClass=kolabSharedFolder)(kolabFolderType=event)(mail=*)" 0029 "(|(cn=%1)(description=%1)(kolabDescAttribute=%1))")); 0030 0031 connect(mLdapSearchCollections, 0032 qOverload<const KLDAPWidgets::LdapResultObject::List &>(&KLDAPWidgets::LdapClientSearch ::searchData), 0033 this, 0034 &ResourceModel::slotLDAPCollectionData); 0035 connect(mLdapSearch, 0036 qOverload<const KLDAPWidgets::LdapResultObject::List &>(&KLDAPWidgets::LdapClientSearch::searchData), 0037 this, 0038 &ResourceModel::slotLDAPSearchData); 0039 0040 mLdapSearchCollections->startSearch(QStringLiteral("*")); 0041 } 0042 0043 ResourceModel::~ResourceModel() = default; 0044 0045 int ResourceModel::columnCount(const QModelIndex & /* parent */) const 0046 { 0047 return mRootItem->columnCount(); 0048 } 0049 0050 QVariant ResourceModel::data(const QModelIndex &index, int role) const 0051 { 0052 if (!index.isValid()) { 0053 return {}; 0054 } 0055 0056 if (role == Qt::EditRole || role == Qt::DisplayRole) { 0057 return getItem(index)->data(index.column()); 0058 } else if (role == Resource) { 0059 ResourceItem *p = getItem(parent(index)); 0060 return QVariant::fromValue(p->child(index.row())); 0061 } else if (role == FullName) { 0062 ResourceItem *item = getItem(index); 0063 return KEmailAddress::normalizedAddress(item->data(QStringLiteral("cn")).toString(), item->data(QStringLiteral("mail")).toString()); 0064 } 0065 0066 return {}; 0067 } 0068 0069 Qt::ItemFlags ResourceModel::flags(const QModelIndex &index) const 0070 { 0071 if (!index.isValid()) { 0072 return Qt::NoItemFlags; 0073 } 0074 0075 return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 0076 } 0077 0078 ResourceItem *ResourceModel::getItem(const QModelIndex &index) const 0079 { 0080 if (index.isValid()) { 0081 auto item = static_cast<ResourceItem *>(index.internalPointer()); 0082 if (item) { 0083 return item; 0084 } 0085 } 0086 return mRootItem.data(); 0087 } 0088 0089 QVariant ResourceModel::headerData(int section, Qt::Orientation orientation, int role) const 0090 { 0091 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { 0092 return translateLDAPAttributeForDisplay(mRootItem->data(section).toString()); 0093 } 0094 0095 return {}; 0096 } 0097 0098 QModelIndex ResourceModel::index(int row, int column, const QModelIndex &parent) const 0099 { 0100 ResourceItem *parentItem = getItem(parent); 0101 0102 ResourceItem::Ptr childItem = parentItem->child(row); 0103 if (row < parentItem->childCount() && childItem) { 0104 return createIndex(row, column, childItem.data()); 0105 } else { 0106 return {}; 0107 } 0108 } 0109 0110 QModelIndex ResourceModel::parent(const QModelIndex &index) const 0111 { 0112 if (!index.isValid()) { 0113 return {}; 0114 } 0115 ResourceItem *childItem = getItem(index); 0116 ResourceItem::Ptr parentItem = childItem->parent(); 0117 0118 if (parentItem == mRootItem) { 0119 return {}; 0120 } 0121 0122 return createIndex(parentItem->childNumber(), index.column(), parentItem.data()); 0123 } 0124 0125 bool ResourceModel::removeRows(int position, int rows, const QModelIndex &parent) 0126 { 0127 ResourceItem *parentItem = getItem(parent); 0128 0129 beginRemoveRows(parent, position, position + rows - 1); 0130 bool success = parentItem->removeChildren(position, rows); 0131 endRemoveRows(); 0132 0133 return success; 0134 } 0135 0136 int ResourceModel::rowCount(const QModelIndex &parent) const 0137 { 0138 ResourceItem *parentItem = getItem(parent); 0139 0140 return parentItem->childCount(); 0141 } 0142 0143 void ResourceModel::startSearch(const QString &query) 0144 { 0145 mSearchString = query; 0146 0147 if (mFoundCollection) { 0148 startSearch(); 0149 } 0150 } 0151 0152 void ResourceModel::startSearch() 0153 { 0154 // Delete all resources -> only collection elements are shown 0155 for (int i = 0; i < mRootItem->childCount(); ++i) { 0156 if (mLdapCollections.contains(mRootItem->child(i))) { 0157 QModelIndex parentIndex = index(i, 0, QModelIndex()); 0158 beginRemoveRows(parentIndex, 0, mRootItem->child(i)->childCount() - 1); 0159 (void)mRootItem->child(i)->removeChildren(0, mRootItem->child(i)->childCount()); 0160 endRemoveRows(); 0161 } else { 0162 beginRemoveRows(QModelIndex(), i, i); 0163 (void)mRootItem->removeChildren(i, 1); 0164 endRemoveRows(); 0165 } 0166 } 0167 0168 if (mSearchString.isEmpty()) { 0169 mLdapSearch->startSearch(QStringLiteral("*")); 0170 } else { 0171 mLdapSearch->startSearch(QLatin1Char('*') + mSearchString + QLatin1Char('*')); 0172 } 0173 } 0174 0175 void ResourceModel::slotLDAPCollectionData(const KLDAPWidgets::LdapResultObject::List &results) 0176 { 0177 Q_EMIT layoutAboutToBeChanged(); 0178 0179 mFoundCollection = true; 0180 mLdapCollectionsMap.clear(); 0181 mLdapCollections.clear(); 0182 0183 // qDebug() << "Found ldapCollections"; 0184 0185 for (const KLDAPWidgets::LdapResultObject &result : std::as_const(results)) { 0186 ResourceItem::Ptr item(new ResourceItem(result.object.dn(), mHeaders, *result.client, mRootItem)); 0187 item->setLdapObject(result.object); 0188 0189 (void)mRootItem->insertChild(mRootItem->childCount(), item); 0190 mLdapCollections.insert(item); 0191 0192 // Resources in a collection add this link into ldapCollectionsMap 0193 const auto members = result.object.attributes()[QStringLiteral("uniqueMember")]; 0194 for (const QByteArray &member : members) { 0195 mLdapCollectionsMap.insert(QString::fromLatin1(member), item); 0196 } 0197 } 0198 0199 Q_EMIT layoutChanged(); 0200 0201 startSearch(); 0202 } 0203 0204 void ResourceModel::slotLDAPSearchData(const KLDAPWidgets::LdapResultObject::List &results) 0205 { 0206 for (const KLDAPWidgets::LdapResultObject &result : std::as_const(results)) { 0207 // Add the found items to all collections, where it is member 0208 QList<ResourceItem::Ptr> parents = mLdapCollectionsMap.values(result.object.dn().toString()); 0209 if (parents.isEmpty()) { 0210 parents << mRootItem; 0211 } 0212 0213 for (const ResourceItem::Ptr &parent : std::as_const(parents)) { 0214 ResourceItem::Ptr item(new ResourceItem(result.object.dn(), mHeaders, *result.client, parent)); 0215 item->setLdapObject(result.object); 0216 0217 QModelIndex parentIndex; 0218 if (parent != mRootItem) { 0219 parentIndex = index(parent->childNumber(), 0, parentIndex); 0220 } 0221 beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); 0222 (void)parent->insertChild(parent->childCount(), item); 0223 endInsertRows(); 0224 } 0225 } 0226 } 0227 0228 #include "moc_resourcemodel.cpp"