KLDAP Library
ldapmodel.cpp
00001 /* 00002 This file is part of libkldap. 00003 Copyright (c) 2006 Sean Harmer <sh@theharmers.co.uk> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "ldapmodel.h" 00022 #include "ldapmodel_p.h" 00023 #include "ldapmodelnode_p.h" 00024 #include "ldapsearch.h" 00025 00026 #include <kdebug.h> 00027 #include <klocale.h> 00028 00029 using namespace KLDAP; 00030 00031 LdapModel::LdapModel( QObject *parent ) 00032 : QAbstractItemModel( parent ), 00033 m_d( new LdapModelPrivate( this ) ) 00034 { 00035 m_d->createConnections(); 00036 } 00037 00038 LdapModel::LdapModel( LdapConnection &connection, QObject *parent ) 00039 : QAbstractItemModel( parent ), 00040 m_d( new LdapModelPrivate( this, connection ) ) 00041 { 00042 m_d->createConnections(); 00043 00044 // Populate items from the root object to that representing the baseDN 00045 m_d->populateRootToBaseDN(); 00046 } 00047 00048 LdapModel::~LdapModel() 00049 { 00050 delete m_d; 00051 } 00052 00053 void LdapModel::setConnection( LdapConnection &connection ) 00054 { 00055 m_d->setConnection( connection ); 00056 00057 // Refresh the model 00058 m_d->recreateRootItem(); 00059 00060 // Populate the root object by searching the baseDN 00061 m_d->populateRootToBaseDN(); 00062 } 00063 00064 QModelIndex LdapModel::parent( const QModelIndex &child ) const 00065 { 00066 if ( !child.isValid() ) { 00067 return QModelIndex(); 00068 } 00069 00070 LdapModelNode *childItem = static_cast<LdapModelNode*>( child.internalPointer() ); 00071 LdapModelDNNode *parentItem = childItem->parent(); 00072 00073 if ( parentItem == m_d->rootNode() ) { 00074 return QModelIndex(); 00075 } 00076 00077 return createIndex( parentItem->row(), 0, parentItem ); 00078 } 00079 00080 QModelIndex LdapModel::index( int row, int col, const QModelIndex &parent ) const 00081 { 00082 // Retrieve a pointer to the parent item 00083 LdapModelDNNode *parentItem; 00084 if ( !parent.isValid() ) { 00085 parentItem = m_d->rootNode(); 00086 } else { 00087 parentItem = static_cast<LdapModelDNNode*>( parent.internalPointer() ); 00088 } 00089 00090 LdapModelNode *childItem = parentItem->child( row ); 00091 if ( childItem ) { 00092 return createIndex( row, col, childItem ); 00093 } 00094 kDebug() << "Could not create valid index for row =" << row << ", col =" << col; 00095 return QModelIndex(); 00096 } 00097 00098 QVariant LdapModel::data( const QModelIndex &index, int role ) const 00099 { 00100 if ( !index.isValid() ) { 00101 return QVariant(); 00102 } 00103 00104 if ( role == Qt::DisplayRole ) { 00105 // This is what gets displayed by the view delegates. 00106 LdapModelNode *node = static_cast<LdapModelNode*>( index.internalPointer() ); 00107 if ( node->nodeType() == LdapModelNode::DN ) { 00108 LdapModelDNNode* dn = static_cast<LdapModelDNNode*>( node ); 00109 if ( index.column() == 0 ) { 00110 return dn->dn().rdnString(); 00111 } else { 00112 return QVariant(); 00113 } 00114 } else { 00115 LdapModelAttrNode* attr = static_cast<LdapModelAttrNode*>( node ); 00116 if ( index.column() == 0 ) { 00117 return QVariant( attr->attributeName() ); 00118 } else { 00119 return QVariant( QString( attr->attributeData().constData() ) ); 00120 } 00121 } 00122 } else if ( role == NodeTypeRole ) { 00123 LdapModelNode* node = static_cast<LdapModelNode*>( index.internalPointer() ); 00124 return QVariant( int( node->nodeType() ) ); 00125 } 00126 00131 return QVariant(); 00132 } 00133 00134 bool LdapModel::setData( const QModelIndex &index, 00135 const QVariant &value, 00136 int role ) 00137 { 00138 Q_UNUSED( index ); 00139 Q_UNUSED( value ); 00140 Q_UNUSED( role ); 00141 return false; 00142 } 00143 00144 QVariant LdapModel::headerData( int section, Qt::Orientation orientation, int role ) const 00145 { 00146 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) { 00147 if ( section == 0 ) { 00148 return QString( i18n( "Attribute" ) ); 00149 } else { 00150 return QString( i18n( "Value" ) ); 00151 } 00152 } 00153 00154 return QVariant(); 00155 } 00156 00157 Qt::ItemFlags LdapModel::flags( const QModelIndex &index ) const 00158 { 00160 if ( !index.isValid() ) { 00161 return Qt::ItemIsEnabled; 00162 } 00163 00164 return Qt::ItemFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); 00165 } 00166 00167 int LdapModel::columnCount( const QModelIndex &parent ) const 00168 { 00169 LdapModelDNNode *parentNode = 00170 parent.isValid() ? static_cast<LdapModelDNNode*>( parent.internalPointer() ) : m_d->rootNode(); 00171 return parentNode->columnCount(); 00172 } 00173 00174 int LdapModel::rowCount( const QModelIndex &parent ) const 00175 { 00176 if ( parent.column() > 0 ) { 00177 return 0; 00178 } 00179 00180 const LdapModelDNNode *parentNode = 00181 parent.isValid() ? static_cast<LdapModelDNNode*>( parent.internalPointer() ) : m_d->rootNode(); 00182 return parentNode->childCount(); 00183 } 00184 00185 bool LdapModel::hasChildren( const QModelIndex &parent ) const 00186 { 00187 // We return true unless the item has been populated and we are able to do a definitive test 00188 const LdapModelNode *node = parent.isValid() ? 00189 static_cast<const LdapModelNode*>( parent.internalPointer() ) : 00190 m_d->rootNode(); 00191 00192 if ( node->nodeType() != LdapModelNode::DN ) { 00193 return false; 00194 } 00195 00196 const LdapModelDNNode* parentNode = static_cast<const LdapModelDNNode*>( node ); 00197 if ( !parent.isValid() || parentNode->isPopulated() ) { 00198 return parentNode->childCount() > 0; 00199 } 00200 return true; 00201 } 00202 00203 bool LdapModel::canFetchMore( const QModelIndex &parent ) const 00204 { 00205 const LdapModelDNNode *parentNode = 00206 parent.isValid() ? static_cast<LdapModelDNNode*>( parent.internalPointer() ) : m_d->rootNode(); 00207 return !parentNode->isPopulated(); 00208 } 00209 00210 void LdapModel::fetchMore( const QModelIndex &parent ) 00211 { 00212 LdapModelDNNode *parentNode = 00213 parent.isValid() ? static_cast<LdapModelDNNode*>( parent.internalPointer() ) : m_d->rootNode(); 00214 00215 // Search for the immediate children of parentItem. 00216 m_d->searchResults().clear(); 00217 m_d->setSearchType( LdapModelPrivate::ChildObjects, parentNode ); 00218 m_d->search( parentNode->dn(), // DN to search from 00219 LdapUrl::One, // What to search 00220 QString() ); // Attributes to retrieve 00221 parentNode->setPopulated( true ); 00222 } 00223 00224 bool LdapModel::insertRows( int row, int count, 00225 const QModelIndex &parent ) 00226 { 00227 Q_UNUSED( row ); 00228 Q_UNUSED( count ); 00229 Q_UNUSED( parent ); 00230 return false; 00231 } 00232 00233 bool LdapModel::removeRows( int row, int count, 00234 const QModelIndex &parent ) 00235 { 00236 Q_UNUSED( row ); 00237 Q_UNUSED( count ); 00238 Q_UNUSED( parent ); 00239 return false; 00240 } 00241 00242 void LdapModel::sort( int column, Qt::SortOrder order ) 00243 { 00244 Q_UNUSED( column ); 00245 Q_UNUSED( order ); 00246 } 00247 00248 Qt::DropActions LdapModel::supportedDropActions() const 00249 { 00250 return Qt::MoveAction; 00251 } 00252 00253 QMimeData *LdapModel::mimeData( const QModelIndexList &indexes ) const 00254 { 00255 Q_UNUSED( indexes ); 00256 return 0; 00257 } 00258 00259 bool LdapModel::dropMimeData( const QMimeData *data, Qt::DropAction action, 00260 int row, int column, const QModelIndex &parent ) 00261 { 00263 Q_UNUSED( data ); 00264 Q_UNUSED( action ); 00265 Q_UNUSED( row ); 00266 Q_UNUSED( column ); 00267 Q_UNUSED( parent ); 00268 return false; 00269 } 00270 00271 bool LdapModel::hasChildrenOfType( const QModelIndex &parent, LdapDataType type ) const 00272 { 00273 // Map from LdapDataType to our internal NodeType 00274 LdapModelNode::NodeType nodeType; 00275 switch ( type ) { 00276 case Attribute: 00277 nodeType = LdapModelNode::Attr; 00278 break; 00279 00280 case DistinguishedName: 00281 default: 00282 nodeType = LdapModelNode::DN; 00283 break; 00284 } 00285 00286 const LdapModelNode *node = parent.isValid() ? 00287 static_cast<const LdapModelNode*>( parent.internalPointer() ) : 00288 m_d->rootNode(); 00289 00290 const LdapModelDNNode* parentNode = static_cast<const LdapModelDNNode*>( node ); 00291 if ( !parent.isValid() || parentNode->isPopulated() ) { 00292 // Check to see if the parent has any children of the specified type 00293 const QList<LdapModelNode*>& children = parentNode->children(); 00294 foreach ( LdapModelNode *child, children ) { 00295 if ( child->nodeType() == nodeType ) { 00296 return true; 00297 } 00298 } 00299 00300 // Either there are no children or only children of a different type 00301 return false; 00302 } 00303 00304 // If the node is not populated or is the root node (invalid), then return 00305 // true to be on the safe side. 00306 return true; 00307 } 00308 00309 void LdapModel::revert() 00310 { 00311 00312 } 00313 00314 bool LdapModel::submit() 00315 { 00316 return false; 00317 } 00318 00319 #include "ldapmodel.moc"