/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** 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 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ //![code] #include "qdeclarativefolderlistmodel.h" #include #include #include QT_BEGIN_NAMESPACE class QDeclarativeFolderListModelPrivate { public: QDeclarativeFolderListModelPrivate() : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0) { nameFilters << QLatin1String("*"); } void updateSorting() { QDir::SortFlags flags = 0; switch(sortField) { case QDeclarativeFolderListModel::Unsorted: flags |= QDir::Unsorted; break; case QDeclarativeFolderListModel::Name: flags |= QDir::Name; break; case QDeclarativeFolderListModel::Time: flags |= QDir::Time; break; case QDeclarativeFolderListModel::Size: flags |= QDir::Size; break; case QDeclarativeFolderListModel::Type: flags |= QDir::Type; break; } if (sortReversed) flags |= QDir::Reversed; model.setSorting(flags); } QDirModel model; QUrl folder; QStringList nameFilters; QModelIndex folderIndex; QDeclarativeFolderListModel::SortField sortField; bool sortReversed; int count; }; /*! \qmlclass FolderListModel \brief The FolderListModel provides a model of the contents of a folder in a filesystem. FolderListModel provides access to the local filesystem. The \e folder property specifies the folder to list. Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system. This type is made available by importing the \c Qt.labs.folderlistmodel module. \e {Elements in the Qt.labs module are not guaranteed to remain compatible in future versions.} \bold{import Qt.labs.folderlistmodel 1.0} The roles available are: \list \o fileName \o filePath \endlist Additionally a file entry can be differentiated from a folder entry via the \l isFolder() method. */ QDeclarativeFolderListModel::QDeclarativeFolderListModel(QObject *parent) : QAbstractListModel(parent) { QHash roles; roles[FileNameRole] = "fileName"; roles[FilePathRole] = "filePath"; setRoleNames(roles); d = new QDeclarativeFolderListModelPrivate; d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot); connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int)) , this, SLOT(inserted(const QModelIndex&,int,int))); connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int)) , this, SLOT(removed(const QModelIndex&,int,int))); connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&)) , this, SLOT(dataChanged(const QModelIndex&,const QModelIndex&))); connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh())); connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh())); } QDeclarativeFolderListModel::~QDeclarativeFolderListModel() { delete d; } QVariant QDeclarativeFolderListModel::data(const QModelIndex &index, int role) const { QVariant rv; QModelIndex modelIndex = d->model.index(index.row(), 0, d->folderIndex); if (modelIndex.isValid()) { if (role == FileNameRole) rv = d->model.data(modelIndex, QDirModel::FileNameRole).toString(); else if (role == FilePathRole) rv = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString()); } return rv; } int QDeclarativeFolderListModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); return d->count; } /*! \qmlproperty string FolderListModel::folder The \a folder property holds the folder the model is currently providing. It is a URL, but must be a file: or qrc: URL (or relative to such a URL). */ QUrl QDeclarativeFolderListModel::folder() const { return d->folder; } void QDeclarativeFolderListModel::setFolder(const QUrl &folder) { if (folder == d->folder) return; QModelIndex index = d->model.index(folder.toLocalFile()); if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) { d->folder = folder; QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); emit folderChanged(); } } QUrl QDeclarativeFolderListModel::parentFolder() const { QString localFile = d->folder.toLocalFile(); if (!localFile.isEmpty()) { QDir dir(localFile); #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN) if (dir.isRoot()) dir.setPath(""); else #endif dir.cdUp(); localFile = dir.path(); } else { int pos = d->folder.path().lastIndexOf(QLatin1Char('/')); if (pos == -1) return QUrl(); localFile = d->folder.path().left(pos); } return QUrl::fromLocalFile(localFile); } /*! \qmlproperty list FolderListModel::nameFilters The \a nameFilters property contains a list of filename filters. The filters may include the ? and * wildcards. The example below filters on PNG and JPEG files: \code FolderListModel { nameFilters: [ "*.png", "*.jpg" ] } \endcode */ QStringList QDeclarativeFolderListModel::nameFilters() const { return d->nameFilters; } void QDeclarativeFolderListModel::setNameFilters(const QStringList &filters) { d->nameFilters = filters; d->model.setNameFilters(d->nameFilters); } void QDeclarativeFolderListModel::classBegin() { } void QDeclarativeFolderListModel::componentComplete() { if (!d->folder.isValid() || !QDir().exists(d->folder.toLocalFile())) setFolder(QUrl(QLatin1String("file://")+QDir::currentPath())); if (!d->folderIndex.isValid()) QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection); } QDeclarativeFolderListModel::SortField QDeclarativeFolderListModel::sortField() const { return d->sortField; } void QDeclarativeFolderListModel::setSortField(SortField field) { if (field != d->sortField) { d->sortField = field; d->updateSorting(); } } bool QDeclarativeFolderListModel::sortReversed() const { return d->sortReversed; } void QDeclarativeFolderListModel::setSortReversed(bool rev) { if (rev != d->sortReversed) { d->sortReversed = rev; d->updateSorting(); } } /*! \qmlmethod bool FolderListModel::isFolder(int index) Returns true if the entry \a index is a folder; otherwise returns false. */ bool QDeclarativeFolderListModel::isFolder(int index) const { if (index != -1) { QModelIndex idx = d->model.index(index, 0, d->folderIndex); if (idx.isValid()) return d->model.isDir(idx); } return false; } void QDeclarativeFolderListModel::refresh() { d->folderIndex = QModelIndex(); if (d->count) { emit beginRemoveRows(QModelIndex(), 0, d->count); d->count = 0; emit endRemoveRows(); } d->folderIndex = d->model.index(d->folder.toLocalFile()); int newcount = d->model.rowCount(d->folderIndex); if (newcount) { emit beginInsertRows(QModelIndex(), 0, newcount-1); d->count = newcount; emit endInsertRows(); } } void QDeclarativeFolderListModel::inserted(const QModelIndex &index, int start, int end) { if (index == d->folderIndex) { emit beginInsertRows(QModelIndex(), start, end); d->count = d->model.rowCount(d->folderIndex); emit endInsertRows(); } } void QDeclarativeFolderListModel::removed(const QModelIndex &index, int start, int end) { if (index == d->folderIndex) { emit beginRemoveRows(QModelIndex(), start, end); d->count = d->model.rowCount(d->folderIndex); emit endRemoveRows(); } } void QDeclarativeFolderListModel::dataChanged(const QModelIndex &start, const QModelIndex &end) { if (start.parent() == d->folderIndex) emit dataChanged(index(start.row(),0), index(end.row(),0)); } /*! \qmlproperty bool FolderListModel::showDirs If true (the default), directories are included in the model. Note that the nameFilters are ignored for directories. */ bool QDeclarativeFolderListModel::showDirs() const { return d->model.filter() & QDir::AllDirs; } void QDeclarativeFolderListModel::setShowDirs(bool on) { if (!(d->model.filter() & QDir::AllDirs) == !on) return; if (on) d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives); else d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives)); } /*! \qmlproperty bool FolderListModel::showDotAndDotDot If true, the "." and ".." directories are included in the model. The default is false. */ bool QDeclarativeFolderListModel::showDotAndDotDot() const { return !(d->model.filter() & QDir::NoDotAndDotDot); } void QDeclarativeFolderListModel::setShowDotAndDotDot(bool on) { if (!(d->model.filter() & QDir::NoDotAndDotDot) == on) return; if (on) d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot); else d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot); } /*! \qmlproperty bool FolderListModel::showOnlyReadable If true, only readable files and directories are shown. The default is false. */ bool QDeclarativeFolderListModel::showOnlyReadable() const { return d->model.filter() & QDir::Readable; } void QDeclarativeFolderListModel::setShowOnlyReadable(bool on) { if (!(d->model.filter() & QDir::Readable) == !on) return; if (on) d->model.setFilter(d->model.filter() | QDir::Readable); else d->model.setFilter(d->model.filter() & ~QDir::Readable); } //![code] QT_END_NAMESPACE