• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdeedu
  • Sitemap
  • Contact Us
 

kalzium

directorytreemodel.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002   DirectoryTreeModel - model for multiple directories / files
00003 
00004   Copyright (C) 2008 Geoffrey R. Hutchison
00005 
00006   Inspired by example code from Qt/Examples by Trolltech.
00007 
00008   This file is part of the Avogadro molecular editor project.
00009   For more information, see <http://avogadro.sourceforge.net/>
00010 
00011   Avogadro is free software; you can redistribute it and/or modify
00012   it under the terms of the GNU General Public License as published by
00013   the Free Software Foundation; either version 2 of the License, or
00014   (at your option) any later version.
00015 
00016   Avogadro is distributed in the hope that it will be useful,
00017   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019   GNU General Public License for more details.
00020 
00021   You should have received a copy of the GNU General Public License
00022   along with this program; if not, write to the Free Software
00023   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00024   02110-1301, USA.
00025  **********************************************************************/
00026 
00027 #include "directorytreemodel.h"
00028 
00029 #include <avogadro/filetreeitem.h>
00030 
00031 #include <QDirIterator>
00032 
00033 namespace Avogadro {
00034 
00035   DirectoryTreeModel::DirectoryTreeModel(const QString &dirList, QObject *parent)
00036     : QAbstractItemModel(parent), _directoryList(dirList.split('\n'))
00037   {
00038     QList<QVariant> rootData;
00039     rootData << "Name"; // This is the header row -- add more columns, e.g. file size, etc.
00040     _rootItem = new FileTreeItem(rootData);
00041 
00042     setupModelData(_directoryList, _rootItem);
00043   }
00044 
00045   DirectoryTreeModel::DirectoryTreeModel(const QStringList &dirList, QObject *parent)
00046   : QAbstractItemModel(parent), _directoryList(dirList)
00047   {
00048     QList<QVariant> rootData;
00049     rootData << "Name"; // This is the header row -- add more columns here
00050     _rootItem = new FileTreeItem(rootData);
00051 
00052     setupModelData(_directoryList, _rootItem);
00053   }
00054 
00055   DirectoryTreeModel::~DirectoryTreeModel()
00056   {
00057     delete _rootItem;
00058   }
00059 
00060   int DirectoryTreeModel::columnCount(const QModelIndex &parent) const
00061   {
00062     if (parent.isValid()) {
00063       FileTreeItem* item = static_cast<FileTreeItem*>(parent.internalPointer());
00064       if (!item)
00065         return 0;
00066       else
00067         return item->columnCount();
00068     }
00069     else
00070       return _rootItem->columnCount();
00071   }
00072 
00073   QVariant DirectoryTreeModel::data(const QModelIndex &index, int role) const
00074   {
00075     if (!index.isValid())
00076       return QVariant();
00077 
00078     if (role != Qt::DisplayRole)
00079       return QVariant();
00080 
00081     FileTreeItem *item = static_cast<FileTreeItem*>(index.internalPointer());
00082     if (!item)
00083       return QVariant();
00084 
00085     return item->data(index.column());
00086   }
00087 
00088   QString DirectoryTreeModel::filePath(const QModelIndex &index) const
00089   {
00090     if (!index.isValid())
00091       return QString();
00092 
00093     FileTreeItem *item = static_cast<FileTreeItem*>(index.internalPointer());
00094     if (!item)
00095       return QString();
00096 
00097     return item->filePath(); // This is a special property of our tree items and isn't user-visible
00098   }
00099 
00100   Qt::ItemFlags DirectoryTreeModel::flags(const QModelIndex &index) const
00101   {
00102     if (!index.isValid())
00103       return 0;
00104 
00105     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00106   }
00107 
00108   QVariant DirectoryTreeModel::headerData(int section, Qt::Orientation orientation,
00109                                           int role) const
00110   {
00111     if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
00112       return _rootItem->data(section);
00113 
00114     return QVariant();
00115   }
00116 
00117   QModelIndex DirectoryTreeModel::index(int row, int column, const QModelIndex &parent)
00118     const
00119   {
00120     if (!hasIndex(row, column, parent))
00121       return QModelIndex();
00122 
00123     FileTreeItem *parentItem = NULL;
00124 
00125     if (!parent.isValid())
00126       parentItem = _rootItem;
00127     else
00128       parentItem = static_cast<FileTreeItem*>(parent.internalPointer());
00129 
00130     if (!parentItem)
00131       return QModelIndex();
00132 
00133     FileTreeItem *childItem = parentItem->child(row);
00134     if (childItem)
00135       return createIndex(row, column, childItem);
00136     else
00137       return QModelIndex();
00138   }
00139 
00140   QModelIndex DirectoryTreeModel::parent(const QModelIndex &index) const
00141   {
00142     if (!index.isValid())
00143       return QModelIndex();
00144 
00145     FileTreeItem *childItem = static_cast<FileTreeItem*>(index.internalPointer());
00146     if (!childItem)
00147       return QModelIndex();
00148 
00149     FileTreeItem *parentItem = childItem->parent();
00150 
00151     if (!parentItem || parentItem == _rootItem)
00152       return QModelIndex();
00153 
00154     return createIndex(parentItem->row(), 0, parentItem);
00155   }
00156 
00157   int DirectoryTreeModel::rowCount(const QModelIndex &parent) const
00158   {
00159     FileTreeItem *parentItem;
00160     if (parent.column() > 0)
00161       return 0;
00162 
00163     if (!parent.isValid())
00164       parentItem = _rootItem;
00165     else
00166       parentItem = static_cast<FileTreeItem*>(parent.internalPointer());
00167 
00168     if (!parentItem)
00169       return 0;
00170       
00171     return parentItem->childCount();
00172   }
00173 
00174   const QStringList &DirectoryTreeModel::directoryList() const
00175   {
00176     return _directoryList;
00177   }
00178 
00179   void DirectoryTreeModel::setDirectoryList(const QStringList &dirList)
00180   {
00181     _directoryList = dirList;
00182     setupModelData(_directoryList, _rootItem);
00183   }
00184 
00185   void DirectoryTreeModel::appendDirectory(const QString &path)
00186   {
00187     _directoryList.append(path);
00188     setupModelData(_directoryList, _rootItem);
00189   }
00190 
00191   // HELPER function: return the number of directories in the path
00192   int directoryDepth(QString path)
00193   {
00194     // Split will count the first separator (e.g. /) and give an extra, empty string
00195     return path.split(QDir::separator()).count() - 1;
00196   }
00197 
00198   // HELPER function: return the name of the last directory
00199   QString lastDirectory(QFileInfo fileInfo)
00200   {
00201     QStringList directoryPath = fileInfo.filePath().split(QDir::separator());
00202     if (fileInfo.isFile())
00203       return directoryPath[directoryPath.size() - 2]; // next to last item
00204     else // must be a directory, since we only iterator over files or dirs
00205       return directoryPath[directoryPath.size() - 1]; // last item
00206   }
00207 
00208   void DirectoryTreeModel::setupModelData(const QStringList &dirList, FileTreeItem *parent)
00209   {
00210     emit layoutAboutToBeChanged(); // we need to tell the view that the data is going to change
00211     parent->deleteChildren(); // remove any previous data
00212 
00213     int position = 0; // current number of subdirectories (i.e., the relative path depth)
00214     int absoluteDepth = 0; // depth of the parent directory
00215   
00216     foreach (const QString& dir, dirList) {
00217       QDir currentDir(dir);
00218 
00219       if (currentDir.exists()) {
00220         absoluteDepth = directoryDepth(currentDir.absolutePath());
00221 
00222         QList<FileTreeItem*> parents;
00223         QList<int> indentations; // number of subdirectories for each item in the model
00224         parents << parent;
00225         indentations << 0;          
00226           
00227         // set the first item to be the top-level directory itself
00228         QList<QVariant> topLevel;
00229         topLevel << currentDir.dirName();
00230         parent->appendChild(new FileTreeItem(topLevel, parent));
00231         parents << parents.last()->child(parents.last()->childCount()-1);
00232         indentations << 0;
00233         
00234         QDirIterator dirIterator(currentDir.absolutePath(),
00235                              QDir::Dirs | QDir::Files | QDir::Readable 
00236                                  | QDir::NoSymLinks | QDir::NoDotAndDotDot,
00237                              QDirIterator::Subdirectories);
00238           
00239         do {
00240           dirIterator.next();
00241           position = directoryDepth(dirIterator.filePath()) - absoluteDepth;
00242 
00243           // First handle the case where we just moved up some directory levels
00244           if (position < indentations.last()) {
00245             while (position < indentations.last() && parents.count() > 0) {
00246               parents.pop_back();
00247               indentations.pop_back();
00248             }
00249           }           
00250 
00251           // If this is a real directory, add it as a new subdirectory
00252           if (dirIterator.fileInfo().isDir() && !dirIterator.fileInfo().isBundle()) {
00253             
00254             // insert a new nested directory
00255             QList<QVariant> dirData;
00256             dirData << dirIterator.fileName();
00257             parents.last()->appendChild(new FileTreeItem(dirData, parents.last()));
00258             // Now the new child becomes the parent for any files in that directory
00259             parents << parents.last()->child(parents.last()->childCount()-1);
00260             indentations << position + 1;
00261 
00262             continue;
00263           }
00264 
00265           // check to see if its an excluded file
00266           // (hidden or not readable or a Mac OS X bundle
00267           if (dirIterator.fileInfo().isHidden() 
00268               || !dirIterator.fileInfo().isReadable()
00269               || dirIterator.fileInfo().isBundle())
00270             continue;
00271           
00272           // OK, this is a file, and we've set the correct path structure
00273           // Add the filename as the first column
00274           QList<QVariant> columnData;
00275           columnData << dirIterator.fileName();
00276                         
00277           // Append a new item to the current parent's list of children.
00278           parents.last()->appendChild(new FileTreeItem(columnData, parents.last(), dirIterator.filePath()));
00279 
00280         } while (dirIterator.hasNext());
00281 
00282       }
00283     }
00284     emit layoutChanged(); // again, tell the view that we're finished
00285   }
00286 
00287 } // end namespace Avogadro
00288 
00289 #include "directorytreemodel.moc"

kalzium

Skip menu "kalzium"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdeedu

Skip menu "kdeedu"
  • kalzium
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  •   docs
  •   src
  • parley
  •   stepcore
Generated for kdeedu by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal