📄 qdirmodel.cpp
字号:
#endif if (childFileName == element) { if (i == pathElements.count() - 1) parent->children[j].stat = true; row = j; break; } } // we couldn't find the path element, we create a new node since we _know_ that the path is valid if (row == -1) { QString newPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element; if (!d->allowAppendChild || !QFileInfo(newPath).isDir()) return QModelIndex(); d->appendChild(parent, newPath); row = parent->children.count() - 1; if (i == pathElements.count() - 1) // always stat children of the last element parent->children[row].stat = true; emit const_cast<QDirModel*>(this)->layoutChanged(); } Q_ASSERT(row >= 0); idx = createIndex(row, 0, static_cast<void*>(&parent->children[row])); Q_ASSERT(idx.isValid()); } if (column != 0) return idx.sibling(idx.row(), column); return idx;}/*! Returns true if the model item \a index represents a directory; otherwise returns false.*/bool QDirModel::isDir(const QModelIndex &index) const{ Q_D(const QDirModel); Q_ASSERT(d->indexValid(index)); QDirModelPrivate::QDirNode *node = d->node(index); return node->info.isDir();}/*! Create a directory with the \a name in the \a parent model item.*/QModelIndex QDirModel::mkdir(const QModelIndex &parent, const QString &name){ Q_D(QDirModel); if (!d->indexValid(parent) || isReadOnly()) return QModelIndex(); QDirModelPrivate::QDirNode *p = d->node(parent); QString path = p->info.absoluteFilePath(); // For the indexOf() method to work, the new directory has to be a direct child of // the parent directory. QDir newDir(name); QDir dir(path); if (newDir.isRelative()) newDir = QDir(path + QLatin1Char('/') + name); QString childName = newDir.dirName(); // Get the singular name of the directory newDir.cdUp(); if (newDir.absolutePath() != dir.absolutePath() || !dir.mkdir(name)) return QModelIndex(); // nothing happened refresh(parent); QStringList entryList = d->entryList(path); int r = entryList.indexOf(childName); QModelIndex i = index(r, 0, parent); // return an invalid index return i;}/*! Removes the directory corresponding to the model item \a index in the directory model and \bold{deletes the corresponding directory from the file system}, returning true if successful. If the directory cannot be removed, false is returned. \warning This function deletes directories from the file system; it does \bold{not} move them to a location where they can be recovered. \sa remove()*/bool QDirModel::rmdir(const QModelIndex &index){ Q_D(QDirModel); if (!d->indexValid(index) || isReadOnly()) return false; QDirModelPrivate::QDirNode *n = d_func()->node(index); if (!n->info.isDir()) { qWarning("rmdir: the node is not a directory"); return false; } QModelIndex par = parent(index); QDirModelPrivate::QDirNode *p = d_func()->node(par); QDir dir = p->info.dir(); // parent dir QString path = n->info.absoluteFilePath(); if (!dir.rmdir(path)) return false; refresh(par); return true;}/*! Removes the model item \a index from the directory model and \bold{deletes the corresponding file from the file system}, returning true if successful. If the item cannot be removed, false is returned. \warning This function deletes files from the file system; it does \bold{not} move them to a location where they can be recovered. \sa rmdir()*/bool QDirModel::remove(const QModelIndex &index){ Q_D(QDirModel); if (!d->indexValid(index) || isReadOnly()) return false; QDirModelPrivate::QDirNode *n = d_func()->node(index); if (n->info.isDir()) return false; QModelIndex par = parent(index); QDirModelPrivate::QDirNode *p = d_func()->node(par); QDir dir = p->info.dir(); // parent dir QString path = n->info.absoluteFilePath(); if (!dir.remove(path)) return false; refresh(par); return true;}/*! Returns the path of the item stored in the model under the \a index given.*/QString QDirModel::filePath(const QModelIndex &index) const{ Q_D(const QDirModel); if (d->indexValid(index)) { QFileInfo fi = fileInfo(index); if (d->resolveSymlinks && fi.isSymLink()) fi = d->resolvedInfo(fi); return QDir::cleanPath(fi.absoluteFilePath()); } return QString(); // root path}/*! Returns the name of the item stored in the model under the \a index given.*/QString QDirModel::fileName(const QModelIndex &index) const{ Q_D(const QDirModel); if (!d->indexValid(index)) return QString(); QFileInfo info = fileInfo(index); if (info.isRoot()) return info.absoluteFilePath(); if (d->resolveSymlinks && info.isSymLink()) info = d->resolvedInfo(info); return info.fileName();}/*! Returns the icons for the item stored in the model under the given \a index.*/QIcon QDirModel::fileIcon(const QModelIndex &index) const{ Q_D(const QDirModel); if (!d->indexValid(index)) return d->iconProvider->icon(QFileIconProvider::Computer); QDirModelPrivate::QDirNode *node = d->node(index); if (node->icon.isNull()) node->icon = d->iconProvider->icon(node->info); return node->icon;}/*! Returns the file information for the specified model \a index. \bold{Note:} If the model index represents a symbolic link in the underlying filing system, the file information returned will contain information about the symbolic link itself, regardless of whether resolveSymlinks is enabled or not. \sa QFileInfo::symLinkTarget()*/QFileInfo QDirModel::fileInfo(const QModelIndex &index) const{ Q_D(const QDirModel); Q_ASSERT(d->indexValid(index)); QDirModelPrivate::QDirNode *node = d->node(index); return node->info;}/*! \fn QObject *QDirModel::parent() const \internal*//* The root node is never seen outside the model.*/void QDirModelPrivate::init(){ filters = QDir::AllEntries | QDir::NoDotAndDotDot; sort = QDir::Name; nameFilters << QLatin1String("*"); root.parent = 0; root.info = QFileInfo(); clear(&root);}QDirModelPrivate::QDirNode *QDirModelPrivate::node(int row, QDirNode *parent) const{ if (row < 0) return 0; bool isDir = !parent || parent->info.isDir(); QDirNode *p = (parent ? parent : &root); if (isDir && !p->populated) populate(p); // will also resolve symlinks if (row >= p->children.count()) { qWarning("node: the row does not exist"); return 0; } return const_cast<QDirNode*>(&p->children.at(row));}QVector<QDirModelPrivate::QDirNode> QDirModelPrivate::children(QDirNode *parent, bool stat) const{ Q_ASSERT(parent); QFileInfoList infoList; if (parent == &root) { parent = 0; infoList = QDir::drives(); } else if (parent->info.isDir()) { //resolve directory links only if requested. if (parent->info.isSymLink() && resolveSymlinks) { QString link = parent->info.symLinkTarget(); if (link.size() > 1 && link.at(link.size() - 1) == QDir::separator()) link.chop(1); if (stat) infoList = entryInfoList(link); else infoList = QDir(link).entryInfoList(nameFilters, QDir::AllEntries | QDir::System); } else { if (stat) infoList = entryInfoList(parent->info.absoluteFilePath()); else infoList = QDir(parent->info.absoluteFilePath()).entryInfoList(nameFilters, QDir::AllEntries | QDir::System); } } QVector<QDirNode> nodes(infoList.count()); for (int i = 0; i < infoList.count(); ++i) { QDirNode &node = nodes[i]; node.parent = parent; node.info = infoList.at(i); node.populated = false; node.stat = shouldStat; } return nodes;}void QDirModelPrivate::_q_refresh(){ Q_Q(QDirModel); q->refresh(toBeRefreshed); toBeRefreshed = QModelIndex();}void QDirModelPrivate::savePersistentIndexes(){ Q_Q(QDirModel); savedPaths.clear(); const QVector<QPersistentModelIndexData*> indexes = persistent.indexes; for (int i = 0; i < indexes.count(); ++i) { QModelIndex idx = indexes.at(i)->index; QString path = q->filePath(idx); savedPaths.append(qMakePair(path, idx.column())); savedPersistentIndexes.append(idx); // make sure the ref >= 1 }}void QDirModelPrivate::restorePersistentIndexes(){ Q_Q(QDirModel); bool allow = allowAppendChild; allowAppendChild = false; for (int i = 0; i < persistent.indexes.count(); ++i) { QModelIndex index; if (i < savedPaths.count()) index = q->index(savedPaths.at(i).first, savedPaths.at(i).second); persistent.indexes.at(i)->index = index; } savedPersistentIndexes.clear(); savedPaths.clear(); allowAppendChild = allow;}QFileInfoList QDirModelPrivate::entryInfoList(const QString &path) const{ const QDir dir(path); return dir.entryInfoList(nameFilters, filters, sort);}QStringList QDirModelPrivate::entryList(const QString &path) const{ const QDir dir(path); return dir.entryList(nameFilters, filters, sort);}QString QDirModelPrivate::name(const QModelIndex &index) const{ const QDirNode *n = node(index); const QFileInfo info = n->info; if (info.isRoot()) { QString name = info.absoluteFilePath();#ifdef Q_OS_WIN if (name.startsWith(QLatin1Char('/'))) // UNC host return info.fileName(); if (name.endsWith(QLatin1Char('/'))) name.chop(1);#endif return name; } return info.fileName();}QString QDirModelPrivate::size(const QModelIndex &index) const{ const QDirNode *n = node(index); if (n->info.isDir()) {#ifdef Q_OS_MAC return QLatin1String("--");#else return QLatin1String("");#endif // Windows - "" // OS X - "--" // Konqueror - "4 KB" // Nautilus - "9 items" (the number of children) } // According to the Si standard KB is 1000 bytes, KiB is 1024 // but on windows sizes are calulated by dividing by 1024 so we do what they do. const quint64 kb = 1024; const quint64 mb = 1024 * kb; const quint64 gb = 1024 * mb; const quint64 tb = 1024 * gb; quint64 bytes = n->info.size(); if (bytes >= tb) return QLocale().toString(bytes / tb) + QString::fromLatin1(" TB"); if (bytes >= gb) return QLocale().toString(bytes / gb) + QString::fromLatin1(" GB"); if (bytes >= mb) return QLocale().toString(bytes / mb) + QString::fromLatin1(" MB"); if (bytes >= kb) return QLocale().toString(bytes / kb) + QString::fromLatin1(" KB"); return QLocale().toString(bytes) + QString::fromLatin1(" bytes");}QString QDirModelPrivate::type(const QModelIndex &index) const{ return iconProvider->type(node(index)->info);}QString QDirModelPrivate::time(const QModelIndex &index) const{#ifndef QT_NO_DATESTRING return node(index)->info.lastModified().toString(Qt::LocalDate);#else Q_UNUSED(index); return QString();#endif}void QDirModelPrivate::appendChild(QDirModelPrivate::QDirNode *parent, const QString &path) const{ QDirModelPrivate::QDirNode node; node.populated = false; node.stat = shouldStat; node.parent = (parent == &root ? 0 : parent); node.info = QFileInfo(path); node.info.setCaching(true); // The following append(node) may reallocate the vector, thus // we need to update the pointers to the childnodes parent. QDirModelPrivate *that = const_cast<QDirModelPrivate *>(this); that->savePersistentIndexes(); parent->children.append(node); for (int i = 0; i < parent->children.count(); ++i) { QDirNode *childNode = &parent->children[i]; for (int j = 0; j < childNode->children.count(); ++j) childNode->children[j].parent = childNode; } that->restorePersistentIndexes();}QFileInfo QDirModelPrivate::resolvedInfo(QFileInfo info){#ifdef Q_OS_WIN // On windows, we cannot create a shortcut to a shortcut. return QFileInfo(info.symLinkTarget());#else QStringList paths; do { QFileInfo link(info.symLinkTarget()); if (link.isRelative()) info.setFile(info.absolutePath(), link.filePath()); else info = link; if (paths.contains(info.absoluteFilePath())) return QFileInfo(); paths.append(info.absoluteFilePath()); } while (info.isSymLink()); return info;#endif}#include "moc_qdirmodel.cpp"#endif // QT_NO_DIRMODEL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -