filetree.cpp Example File
xmlpatterns/filetree/filetree.cpp
 #include <QtCore/QUrl>
 #include <QtCore/QVariant>
 #include <QtXmlPatterns/QXmlNamePool>
 #include "filetree.h"
 FileTree::FileTree(const QXmlNamePool& pool)
   : QSimpleXmlNodeModel(pool),
     m_filterAllowAll(QDir::AllEntries |
                      QDir::AllDirs |
                      QDir::NoDotAndDotDot |
                      QDir::Hidden),
     m_sortFlags(QDir::Name)
 {
     QXmlNamePool np = namePool();
     m_names.resize(7);
     m_names[File]               = QXmlName(np, QLatin1String("file"));
     m_names[Directory]          = QXmlName(np, QLatin1String("directory"));
     m_names[AttributeFileName]  = QXmlName(np, QLatin1String("fileName"));
     m_names[AttributeFilePath]  = QXmlName(np, QLatin1String("filePath"));
     m_names[AttributeSize]      = QXmlName(np, QLatin1String("size"));
     m_names[AttributeMIMEType]  = QXmlName(np, QLatin1String("mimeType"));
     m_names[AttributeSuffix]    = QXmlName(np, QLatin1String("suffix"));
 }
 QXmlNodeModelIndex FileTree::nodeFor(const QString& dirName) const
 {
     QFileInfo dirInfo(QDir::cleanPath(dirName));
     Q_ASSERT(dirInfo.exists());
     return toNodeIndex(dirInfo);
 }
 const QFileInfo&
 FileTree::toFileInfo(const QXmlNodeModelIndex &nodeIndex) const
 {
     return m_fileInfos.at(nodeIndex.data());
 }
 QXmlNodeModelIndex
 FileTree::toNodeIndex(const QFileInfo &fileInfo, Type attributeName) const
 {
     const int indexOf = m_fileInfos.indexOf(fileInfo);
     if (indexOf == -1) {
         m_fileInfos.append(fileInfo);
         return createIndex(m_fileInfos.count()-1, attributeName);
     }
     else
         return createIndex(indexOf, attributeName);
 }
 QXmlNodeModelIndex FileTree::toNodeIndex(const QFileInfo &fileInfo) const
 {
     return toNodeIndex(fileInfo, fileInfo.isDir() ? Directory : File);
 }
 QXmlNodeModelIndex FileTree::nextSibling(const QXmlNodeModelIndex &nodeIndex,
                                          const QFileInfo &fileInfo,
                                          qint8 offset) const
 {
     Q_ASSERT(offset == -1 || offset == 1);
     
     const QXmlNodeModelIndex parent(nextFromSimpleAxis(Parent, nodeIndex));
     if (parent.isNull())
         return QXmlNodeModelIndex();
     
     const QFileInfo parentFI(toFileInfo(parent));
     Q_ASSERT(Type(parent.additionalData()) == Directory);
     const QFileInfoList siblings(QDir(parentFI.absoluteFilePath()).entryInfoList(QStringList(),
                                                                                  m_filterAllowAll,
                                                                                  m_sortFlags));
     Q_ASSERT_X(!siblings.isEmpty(), Q_FUNC_INFO, "Can't happen! We started at a child.");
     
     const int indexOfMe = siblings.indexOf(fileInfo);
     
     const int siblingIndex = indexOfMe + offset;
     if (siblingIndex < 0 || siblingIndex > siblings.count() - 1)
         return QXmlNodeModelIndex();
     else
         return toNodeIndex(siblings.at(siblingIndex));
 }
 QXmlNodeModelIndex
 FileTree::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &nodeIndex) const
 {
     const QFileInfo fi(toFileInfo(nodeIndex));
     const Type type = Type(nodeIndex.additionalData());
     if (type != File && type != Directory) {
         Q_ASSERT_X(axis == Parent, Q_FUNC_INFO, "An attribute only has a parent!");
         return toNodeIndex(fi, Directory);
     }
     switch (axis) {
         case Parent:
             return toNodeIndex(QFileInfo(fi.path()), Directory);
         case FirstChild:
         {
             if (type == File) 
                 return QXmlNodeModelIndex();
             else {
                 Q_ASSERT(type == Directory);
                 Q_ASSERT_X(fi.isDir(), Q_FUNC_INFO, "It isn't really a directory!");
                 const QDir dir(fi.absoluteFilePath());
                 Q_ASSERT(dir.exists());
                 const QFileInfoList children(dir.entryInfoList(QStringList(),
                                                                m_filterAllowAll,
                                                                m_sortFlags));
                 if (children.isEmpty())
                     return QXmlNodeModelIndex();
                 const QFileInfo firstChild(children.first());
                 return toNodeIndex(firstChild);
             }
         }
         case PreviousSibling:
             return nextSibling(nodeIndex, fi, -1);
         case NextSibling:
             return nextSibling(nodeIndex, fi, 1);
     }
     Q_ASSERT_X(false, Q_FUNC_INFO, "Don't ever get here!");
     return QXmlNodeModelIndex();
 }
 QUrl FileTree::documentUri(const QXmlNodeModelIndex &node) const
 {
     Q_UNUSED(node);
     return QUrl("file:);
 }
 QXmlNodeModelIndex::NodeKind
 FileTree::kind(const QXmlNodeModelIndex &node) const
 {
     switch (Type(node.additionalData())) {
         case Directory:
         case File:
             return QXmlNodeModelIndex::Element;
         default:
             return QXmlNodeModelIndex::Attribute;
     }
 }
 QXmlNodeModelIndex::DocumentOrder
 FileTree::compareOrder(const QXmlNodeModelIndex&,
                        const QXmlNodeModelIndex&) const
 {
     return QXmlNodeModelIndex::Precedes;
 }
 QXmlName FileTree::name(const QXmlNodeModelIndex &node) const
 {
     return m_names.at(node.additionalData());
 }
 QXmlNodeModelIndex FileTree::root(const QXmlNodeModelIndex &node) const
 {
     Q_UNUSED(node);
     return toNodeIndex(QFileInfo(QLatin1String("/")));
 }
 QVariant FileTree::typedValue(const QXmlNodeModelIndex &node) const
 {
     const QFileInfo &fi = toFileInfo(node);
     switch (Type(node.additionalData())) {
         case Directory:
             
         case File:
             return QString();
         case AttributeFileName:
             return fi.fileName();
         case AttributeFilePath:
             return fi.filePath();
         case AttributeSize:
             return fi.size();
         case AttributeMIMEType:
             {
                 
                 return QLatin1String("application/octet-stream");
             }
         case AttributeSuffix:
             return fi.suffix();
     }
     Q_ASSERT_X(false, Q_FUNC_INFO, "This line should never be reached.");
     return QString();
 }
 QVector<QXmlNodeModelIndex>
 FileTree::attributes(const QXmlNodeModelIndex &element) const
 {
     QVector<QXmlNodeModelIndex> result;
     
     const QFileInfo &forElement = toFileInfo(element);
     result.append(toNodeIndex(forElement, AttributeFilePath));
     result.append(toNodeIndex(forElement, AttributeFileName));
     if (Type(element.additionalData() == File)) {
         result.append(toNodeIndex(forElement, AttributeSize));
         result.append(toNodeIndex(forElement, AttributeSuffix));
         
     }
     else {
         Q_ASSERT(element.additionalData() == Directory);
     }
     return result;
 }