qfilesystemmodel.cpp 64.89 KiB
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
** $QT_END_LICENSE$
****************************************************************************/
#include "qfilesystemmodel_p.h"
#include "qfilesystemmodel.h"
#include <qlocale.h>
#include <qmimedata.h>
#include <qurl.h>
#include <qdebug.h>
#include <qmessagebox.h>
#include <qapplication.h>
#include <algorithm>
#ifdef Q_OS_WIN
#  include <QtCore/QVarLengthArray>
#  include <qt_windows.h>
#endif
QT_BEGIN_NAMESPACE
#ifndef QT_NO_FILESYSTEMMODEL
/*!
    \enum QFileSystemModel::Roles
    \value FileIconRole
    \value FilePathRole
    \value FileNameRole
    \value FilePermissions
/*!
    \class QFileSystemModel
    \since 4.4
    \brief The QFileSystemModel class provides a data model for the local filesystem.
    \ingroup model-view
    \inmodule QtWidgets
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
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 filter. QFileSystemModel 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(), fileName() and filePath() functions provide information about the underlying files and directories related to items in the model. Directories can be created and removed using mkdir(), rmdir(). \note QFileSystemModel requires an instance of a GUI application. \section1 Example Usage A directory model that displays the contents of a default directory is usually constructed with a parent object: \snippet shareddirmodel/main.cpp 2 A tree view can be used to display the contents of the model \snippet shareddirmodel/main.cpp 4 and the contents of a particular directory can be displayed by setting the tree view's root index: \snippet shareddirmodel/main.cpp 7 The view's root index can be used to control how much of a hierarchical model is displayed. QFileSystemModel provides a convenience function that returns a suitable model index for a path to a directory within the model. \section1 Caching and Performance QFileSystemModel will not fetch any files or directories until setRootPath() is called. This will prevent any unnecessary querying on the file system until that point such as listing the drives on Windows. Unlike QDirModel, QFileSystemModel uses a separate thread to populate itself so it will not cause the main thread to hang as the file system is being queried. Calls to rowCount() will return 0 until the model populates a directory. QFileSystemModel keeps a cache with file information. The cache is automatically kept up to date using the QFileSystemWatcher. \sa {Model Classes} */ /*! \fn bool QFileSystemModel::rmdir(const QModelIndex &index) Removes the directory corresponding to the model item \a index in the file system model and \b{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 \b{not} move them to a location where they can be recovered. \sa remove() */ /*! \fn QIcon QFileSystemModel::fileName(const QModelIndex &index) const Returns the file name for the item stored in the model under the given
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
\a index. */ /*! \fn QIcon QFileSystemModel::fileIcon(const QModelIndex &index) const Returns the icon for the item stored in the model under the given \a index. */ /*! \fn QFileInfo QFileSystemModel::fileInfo(const QModelIndex &index) const Returns the QFileInfo for the item stored in the model under the given \a index. */ QFileInfo QFileSystemModel::fileInfo(const QModelIndex &index) const { Q_D(const QFileSystemModel); return d->node(index)->fileInfo(); } /*! \fn void QFileSystemModel::rootPathChanged(const QString &newPath); This signal is emitted whenever the root path has been changed to a \a newPath. */ /*! \fn void QFileSystemModel::fileRenamed(const QString &path, const QString &oldName, const QString &newName) This signal is emitted whenever a file with the \a oldName is successfully renamed to \a newName. The file is located in in the directory \a path. */ /*! \since 4.7 \fn void QFileSystemModel::directoryLoaded(const QString &path) This signal is emitted when the gatherer thread has finished to load the \a path. */ /*! \fn bool QFileSystemModel::remove(const QModelIndex &index) Removes the model item \a index from the file system model and \b{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 \b{not} move them to a location where they can be recovered. \sa rmdir() */ bool QFileSystemModel::remove(const QModelIndex &aindex) { const QString path = filePath(aindex); #ifndef QT_NO_FILESYSTEMWATCHER QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func()); d->fileInfoGatherer.removePath(path); #endif if (QFileInfo(path).isFile()) return QFile::remove(path); return QDir(path).removeRecursively(); } /*! Constructs a file system model with the given \a parent.
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
*/ QFileSystemModel::QFileSystemModel(QObject *parent) : QAbstractItemModel(*new QFileSystemModelPrivate, parent) { Q_D(QFileSystemModel); d->init(); } /*! \internal */ QFileSystemModel::QFileSystemModel(QFileSystemModelPrivate &dd, QObject *parent) : QAbstractItemModel(dd, parent) { Q_D(QFileSystemModel); d->init(); } /*! Destroys this file system model. */ QFileSystemModel::~QFileSystemModel() { } /*! \reimp */ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &parent) const { Q_D(const QFileSystemModel); if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) return QModelIndex(); // get the parent node QFileSystemModelPrivate::QFileSystemNode *parentNode = (d->indexValid(parent) ? d->node(parent) : const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&d->root)); Q_ASSERT(parentNode); // now get the internal pointer for the index const QString &childName = parentNode->visibleChildren.at(d->translateVisibleLocation(parentNode, row)); const QFileSystemModelPrivate::QFileSystemNode *indexNode = parentNode->children.value(childName); Q_ASSERT(indexNode); return createIndex(row, column, const_cast<QFileSystemModelPrivate::QFileSystemNode*>(indexNode)); } /*! \overload Returns the model item index for the given \a path and \a column. */ QModelIndex QFileSystemModel::index(const QString &path, int column) const { Q_D(const QFileSystemModel); QFileSystemModelPrivate::QFileSystemNode *node = d->node(path, false); return d->index(node, column); } /*! \internal Return the QFileSystemNode that goes to index. */ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QModelIndex &index) const { if (!index.isValid()) return const_cast<QFileSystemNode*>(&root); QFileSystemModelPrivate::QFileSystemNode *indexNode = static_cast<QFileSystemModelPrivate::QFileSystemNode*>(index.internalPointer()); Q_ASSERT(indexNode);