返回

Qt实现文件树

发布时间:2023-05-17 08:51:22 159
#include 
#include
#include
#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);

// Get the context node's parent.
const QXmlNodeModelIndex parent(nextFromSimpleAxis(Parent, nodeIndex));

if (parent.isNull())
return QXmlNodeModelIndex();

// Get the parent's child list.
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.");

// Find the index of the child where we started.
const int indexOfMe = siblings.indexOf(fileInfo);

// Apply the offset.
const int siblingIndex = indexOfMe + offset;
if (siblingIndex < 0 || siblingIndex > siblings.count() - 1)
return QXmlNodeModelIndex();
else
return toNodeIndex(siblings.at(siblingIndex));
}
//! [5]


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) // A file has no children.
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::Is;
}

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:
// deliberate fall through.
case File:
return QString();
case AttributeFileName:
return fi.fileName();
case AttributeFilePath:
return fi.filePath();
case AttributeSize:
return fi.size();
case AttributeMIMEType:
{
/* We don't have any MIME detection code currently, so return
* the most generic one. */
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;

/* Both elements has this attribute. */
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));
//result.append(toNodeIndex(forElement, AttributeMIMEType));
}
else {
Q_ASSERT(element.additionalData() == Directory);
}

return result;
}
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
C语言习题 2023-05-17 06:01:50