📄 qdirmodel.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qdirmodel.h"#ifndef QT_NO_DIRMODEL#include <qstack.h>#include <qfile.h>#include <qurl.h>#include <qmime.h>#include <qpair.h>#include <qvector.h>#include <qobject.h>#include <qdatetime.h>#include <qlocale.h>#include <qstyle.h>#include <qapplication.h>#include <private/qabstractitemmodel_p.h>#include <qdebug.h>#if defined(Q_WS_WIN)# include "qt_windows.h"#endif/*! \class QFileIconProvider \brief The QFileIconProvider class provides file icon for the QDirModel class.*//*! \enum QFileIconProvider::IconType \value Computer \value Desktop \value Trashcan \value Network \value Drive \value Folder \value File*//*! \enum QDirModel::Roles \value FileIconRole \value FilePathRole \value FileNameRole*/class QFileIconProviderPrivate{ Q_DECLARE_PUBLIC(QFileIconProvider)public: QFileIconProviderPrivate(); QIcon file; QIcon fileLink; QIcon directory; QIcon directoryLink; QIcon harddisk; QIcon floppy; QIcon cdrom; QIcon ram; QIcon network; QIcon computer; QIcon desktop; QIcon trashcan; QIcon generic; QFileIconProvider *q_ptr;};QFileIconProviderPrivate::QFileIconProviderPrivate(){ QStyle *style = QApplication::style(); file = QIcon(style->standardPixmap(QStyle::SP_FileIcon)); fileLink = QIcon(style->standardPixmap(QStyle::SP_FileLinkIcon)); directory = QIcon(style->standardPixmap(QStyle::SP_DirClosedIcon)); directory.addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon), QIcon::Normal, QIcon::On); directoryLink = QIcon(style->standardPixmap(QStyle::SP_DirLinkIcon)); harddisk = QIcon(style->standardPixmap(QStyle::SP_DriveHDIcon)); floppy = QIcon(style->standardPixmap(QStyle::SP_DriveFDIcon)); cdrom = QIcon(style->standardPixmap(QStyle::SP_DriveCDIcon)); generic = ram = harddisk; // FIXME network = QIcon(style->standardPixmap(QStyle::SP_DriveNetIcon)); computer = QIcon(style->standardPixmap(QStyle::SP_ComputerIcon)); desktop = QIcon(style->standardPixmap(QStyle::SP_DesktopIcon)); trashcan = QIcon(style->standardPixmap(QStyle::SP_TrashIcon));}/*! Constructs a file icon provider.*/QFileIconProvider::QFileIconProvider() : d_ptr(new QFileIconProviderPrivate){}/*! Destroys the file icon provider.*/QFileIconProvider::~QFileIconProvider(){ delete d_ptr;}/*! Returns an icon set for the given \a type.*/QIcon QFileIconProvider::icon(IconType type) const{ switch (type) { case Computer: return d_ptr->computer; case Desktop: return d_ptr->desktop; case Trashcan: return d_ptr->trashcan; case Network: return d_ptr->network; case Drive: return d_ptr->generic; case Folder: return d_ptr->directory; case File: return d_ptr->file; default: break; }; return QIcon();}/*! Returns an icon for the file described by \a info.*/QIcon QFileIconProvider::icon(const QFileInfo &info) const{ if (info.isRoot())#ifdef Q_OS_WIN { uint type = DRIVE_UNKNOWN; QT_WA({ type = GetDriveTypeW((wchar_t *)info.absoluteFilePath().utf16()); }, { type = GetDriveTypeA(info.absoluteFilePath().toLocal8Bit()); }); switch (type) { case DRIVE_REMOVABLE: return d_ptr->floppy; case DRIVE_FIXED: return d_ptr->harddisk; case DRIVE_REMOTE: return d_ptr->network; case DRIVE_CDROM: return d_ptr->cdrom; case DRIVE_RAMDISK: return d_ptr->ram; case DRIVE_UNKNOWN: return d_ptr->generic; case DRIVE_NO_ROOT_DIR: default: return d_ptr->generic; } }#else return d_ptr->generic;#endif if (info.isFile()) if (info.isSymLink()) return d_ptr->fileLink; else return d_ptr->file; if (info.isDir()) if (info.isSymLink()) return d_ptr->directoryLink; else return d_ptr->directory; return QIcon();}/*! Returns the type of the file described by \a info.*/QString QFileIconProvider::type(const QFileInfo &info) const{ if (info.isRoot()) return QApplication::translate("QFileDialog", "Drive"); if (info.isFile()) return info.suffix() + QLatin1String(" ") + QApplication::translate("QFileDialog", "File"); if (info.isDir()) return QApplication::translate("QFileDialog", "Directory"); if (info.isSymLink()) return QApplication::translate("QFileDialog", "Symbolic Link"); return QApplication::translate("QFileDialog", "Unknown");}class QDirModelPrivate : public QAbstractItemModelPrivate{ Q_DECLARE_PUBLIC(QDirModel)public: struct QDirNode { QDirNode() : parent(0), populated(false), stat(false) {} ~QDirNode() { children.clear(); } QDirNode *parent; QFileInfo info; QIcon icon; // cache the icon mutable QVector<QDirNode> children; mutable bool populated; // have we read the children mutable bool stat; }; QDirModelPrivate() : resolveSymlinks(true), readOnly(true), lazyChildCount(false), allowAppendChild(true), iconProvider(&defaultProvider), shouldStat(true) // ### This is set to false by QFileDialog { } void init(); QDirNode *node(int row, QDirNode *parent) const; QVector<QDirNode> children(QDirNode *parent, bool stat) const; void _q_refresh(); void savePersistentIndexes(); void restorePersistentIndexes(); QFileInfoList entryInfoList(const QString &path) const; QStringList entryList(const QString &path) const; QString name(const QModelIndex &index) const; QString size(const QModelIndex &index) const; QString type(const QModelIndex &index) const; QString time(const QModelIndex &index) const; void appendChild(QDirModelPrivate::QDirNode *parent, const QString &path) const; static QFileInfo resolvedInfo(QFileInfo info); inline QDirNode *node(const QModelIndex &index) const; inline void populate(QDirNode *parent) const; inline void clear(QDirNode *parent) const; void invalidate(); mutable QDirNode root; bool resolveSymlinks; bool readOnly; bool lazyChildCount; bool allowAppendChild; QDir::Filters filters; QDir::SortFlags sort; QStringList nameFilters; QFileIconProvider *iconProvider; QFileIconProvider defaultProvider; QList< QPair<QString,int> > savedPaths; QList< QPersistentModelIndex > savedPersistentIndexes; QPersistentModelIndex toBeRefreshed; bool shouldStat; // use the "carefull not to stat directories" mode};void qt_setDirModelShouldNotStat(QDirModelPrivate *modelPrivate){ modelPrivate->shouldStat = false;}QDirModelPrivate::QDirNode *QDirModelPrivate::node(const QModelIndex &index) const{ QDirModelPrivate::QDirNode *n = static_cast<QDirModelPrivate::QDirNode*>(index.internalPointer()); Q_ASSERT(n); return n;}void QDirModelPrivate::populate(QDirNode *parent) const{ Q_ASSERT(parent); parent->children = children(parent, parent->stat); parent->populated = true;}void QDirModelPrivate::clear(QDirNode *parent) const{ Q_ASSERT(parent); parent->children.clear(); parent->populated = false;}void QDirModelPrivate::invalidate(){ QStack<const QDirNode*> nodes; nodes.push(&root); while (!nodes.empty()) { const QDirNode *current = nodes.pop(); current->stat = false; const QVector<QDirNode> children = current->children; for (int i = 0; i < children.count(); ++i) nodes.push(&children.at(i)); }}/*! \class QDirModel qdirmodel.h \brief The QDirModel class provides a data model for the local filesystem. \ingroup model-view This class provides access to the local filesystem, providing functions for renaming and removing files and directories, and for creating new directories. In the simplest case, it can be used with a suitable display widget as part of a browser or filer. QDirModel does not store file information internally or cache file data. A directory model that displays the contents of a default directory is usually constructed with a parent object: \quotefromfile snippets/shareddirmodel/main.cpp \skipto QDirModel *model \printuntil QDirModel *model A tree view can be used to display the contents of the model \skipto QTreeView *tree \printuntil tree->setModel( and the contents of a particular directory can be displayed by setting the tree view's root index: \printuntil tree->setRootIndex( The view's root index can be used to control how much of a hierarchical model is displayed. QDirModel provides a convenience function that returns a suitable model index for a path to a directory within the model. QDirModel can be accessed using the standard interface provided by QAbstractItemModel, but it also provides some convenience functions that are specific to a directory model. The fileInfo(), isDir(), name(), and path() functions provide information about the underlying files and directories related to items in the model. Directories can be created and removed using mkdir(), rmdir(), and the model will be automatically updated to take the changes into account. \sa nameFilters(), setFilter(), filter(), {Model/View Programming}, QListView, QTreeView*//*! Constructs a new directory model with the given \a parent. Only those files matching the \a nameFilters and the \a filters are included in the model. The sort order is given by the \a sort flags.*/QDirModel::QDirModel(const QStringList &nameFilters, QDir::Filters filters, QDir::SortFlags sort, QObject *parent) : QAbstractItemModel(*new QDirModelPrivate, parent){ Q_D(QDirModel); // we always start with QDir::drives() d->nameFilters = nameFilters.isEmpty() ? QStringList("*") : nameFilters; d->filters = filters; d->sort = sort; d->root.parent = 0; d->root.info = QFileInfo(); d->clear(&d->root);}/*! Constructs a directory model with the given \a parent.*/QDirModel::QDirModel(QObject *parent) : QAbstractItemModel(*new QDirModelPrivate, parent){ Q_D(QDirModel); d->init();}/*! \internal*/QDirModel::QDirModel(QDirModelPrivate &dd, QObject *parent) : QAbstractItemModel(dd, parent){ Q_D(QDirModel); d->init();}/*! Destroys this directory model.*/QDirModel::~QDirModel(){}/*! Returns the model item index for the item in the \a parent with the given \a row and \a column.*/QModelIndex QDirModel::index(int row, int column, const QModelIndex &parent) const{ Q_D(const QDirModel); // note that rowCount does lazy population if (column < 0 || column >= 4 || row < 0 || parent.column() > 0) return QModelIndex(); // make sure the list of children is up to date QDirModelPrivate::QDirNode *p = (parent.isValid() ? d->node(parent) : &d->root); Q_ASSERT(p); if (!p->populated) d->populate(p); // populate without stat'ing if (row >= p->children.count()) return QModelIndex(); // now get the internal pointer for the index QDirModelPrivate::QDirNode *n = d->node(row, parent.isValid() ? p : 0); Q_ASSERT(n); return createIndex(row, column, n);}/*! Return the parent of the given \a child model item.*/QModelIndex QDirModel::parent(const QModelIndex &child) const{ Q_D(const QDirModel); if (!child.isValid()) return QModelIndex(); QDirModelPrivate::QDirNode *node = d->node(child); QDirModelPrivate::QDirNode *par = (node ? node->parent : 0); if (par == 0) // parent is the root node return QModelIndex(); // get the parent's row const QVector<QDirModelPrivate::QDirNode> children = par->parent ? par->parent->children : d->root.children; Q_ASSERT(children.count() > 0); int row = (par - &(children.at(0))); Q_ASSERT(row >= 0); return createIndex(row, 0, par);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -