1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the examples of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qdeclarativefolderlistmodel.h"
46 #include <qdeclarativecontext.h>
48 #ifndef QT_NO_DIRMODEL
52 class QDeclarativeFolderListModelPrivate
55 QDeclarativeFolderListModelPrivate()
56 : sortField(QDeclarativeFolderListModel::Name), sortReversed(false), count(0), showDirs(true), showDots(false), showOnlyReadable(false), insideRefresh(false) {
57 nameFilters << QLatin1String("*");
60 void updateSorting() {
61 QDir::SortFlags flags = 0;
63 case QDeclarativeFolderListModel::Unsorted:
64 flags |= QDir::Unsorted;
66 case QDeclarativeFolderListModel::Name:
69 case QDeclarativeFolderListModel::Time:
72 case QDeclarativeFolderListModel::Size:
75 case QDeclarativeFolderListModel::Type:
81 flags |= QDir::Reversed;
83 model.setSorting(flags);
88 QStringList nameFilters;
89 QModelIndex folderIndex;
90 QDeclarativeFolderListModel::SortField sortField;
95 bool showOnlyReadable;
100 \qmlclass FolderListModel QDeclarativeFolderListModel
101 \ingroup qml-working-with-data
102 \brief The FolderListModel provides a model of the contents of a file system folder.
104 FolderListModel provides access to information about the contents of a folder
105 in the local file system, exposing a list of files to views and other data components.
107 \note This type is made available by importing the \c Qt.labs.folderlistmodel module.
108 \e{Elements in the Qt.labs module are not guaranteed to remain compatible
111 \bold{import Qt.labs.folderlistmodel 1.0}
113 The \l folder property specifies the folder to access. Information about the
114 files and directories in the folder is supplied via the model's interface.
115 Components access names and paths via the following roles:
122 Additionally a file entry can be differentiated from a folder entry via the
127 Various properties can be set to filter the number of files and directories
128 exposed by the model.
130 The \l nameFilters property can be set to contain a list of wildcard filters
131 that are applied to names of files and directories, causing only those that
132 match the filters to be exposed.
134 Directories can be included or excluded using the \l showDirs property, and
135 navigation directories can also be excluded by setting the \l showDotAndDotDot
138 It is sometimes useful to limit the files and directories exposed to those
139 that the user can access. The \l showOnlyReadable property can be set to
142 \section1 Example Usage
144 The following example shows a FolderListModel being used to provide a list
145 of QML files in a \l ListView:
147 \snippet doc/src/snippets/declarative/folderlistmodel.qml 0
149 \section1 Path Separators
151 Qt uses "/" as a universal directory separator in the same way that "/" is
152 used as a path separator in URLs. If you always use "/" as a directory
153 separator, Qt will translate your paths to conform to the underlying
156 \sa {QML Data Models}
159 QDeclarativeFolderListModel::QDeclarativeFolderListModel(QObject *parent)
160 : QAbstractListModel(parent)
162 QHash<int, QByteArray> roles;
163 roles[FileNameRole] = "fileName";
164 roles[FilePathRole] = "filePath";
167 d = new QDeclarativeFolderListModelPrivate;
168 d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot);
169 connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int))
170 , this, SLOT(inserted(const QModelIndex&,int,int)));
171 connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int))
172 , this, SLOT(removed(const QModelIndex&,int,int)));
173 connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&))
174 , this, SLOT(handleDataChanged(const QModelIndex&,const QModelIndex&)));
175 connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh()));
176 connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh()));
179 QDeclarativeFolderListModel::~QDeclarativeFolderListModel()
184 QVariant QDeclarativeFolderListModel::data(const QModelIndex &index, int role) const
187 QModelIndex modelIndex = d->model.index(index.row(), 0, d->folderIndex);
188 if (modelIndex.isValid()) {
189 if (role == FileNameRole)
190 rv = d->model.data(modelIndex, QDirModel::FileNameRole).toString();
191 else if (role == FilePathRole)
192 rv = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString());
198 \qmlproperty int FolderListModel::count
200 Returns the number of items in the current folder that match the
203 int QDeclarativeFolderListModel::rowCount(const QModelIndex &parent) const
210 \qmlproperty string FolderListModel::folder
212 The \a folder property holds a URL for the folder that the model is
215 The value is a URL expressed as a string, and must be a \c file: or \c qrc:
216 URL, or a relative URL.
218 By default, the value is an invalid URL.
220 QUrl QDeclarativeFolderListModel::folder() const
225 void QDeclarativeFolderListModel::setFolder(const QUrl &folder)
227 if (folder == d->folder)
230 QModelIndex index = d->model.index(folder.toLocalFile()); // This can modify the filtering rules.
231 if ((index.isValid() && d->model.isDir(index)) || folder.toLocalFile().isEmpty()) {
233 QMetaObject::invokeMethod(this, "resetFiltering", Qt::QueuedConnection); // resetFiltering will invoke refresh().
234 emit folderChanged();
238 void QDeclarativeFolderListModel::resetFiltering()
240 // ensure that we reset the filtering rules, because the QDirModel::index()
241 // function isn't quite as const as it claims to be.
242 QDir::Filters filt = d->model.filter();
245 filt |= (QDir::AllDirs | QDir::Drives);
247 filt &= ~(QDir::AllDirs | QDir::Drives);
250 filt &= ~QDir::NoDotAndDotDot;
252 filt |= QDir::NoDotAndDotDot;
254 if (d->showOnlyReadable)
255 filt |= QDir::Readable;
257 filt &= ~QDir::Readable;
259 d->model.setFilter(filt); // this causes a refresh().
263 \qmlproperty url FolderListModel::parentFolder
265 Returns the URL of the parent of of the current \l folder.
267 QUrl QDeclarativeFolderListModel::parentFolder() const
269 QString localFile = d->folder.toLocalFile();
270 if (!localFile.isEmpty()) {
272 #if defined(Q_OS_SYMBIAN) || defined(Q_OS_WIN)
278 localFile = dir.path();
280 int pos = d->folder.path().lastIndexOf(QLatin1Char('/'));
283 localFile = d->folder.path().left(pos);
285 return QUrl::fromLocalFile(localFile);
289 \qmlproperty list<string> FolderListModel::nameFilters
291 The \a nameFilters property contains a list of file name filters.
292 The filters may include the ? and * wildcards.
294 The example below filters on PNG and JPEG files:
298 nameFilters: [ "*.png", "*.jpg" ]
302 \note Directories are not excluded by filters.
304 QStringList QDeclarativeFolderListModel::nameFilters() const
306 return d->nameFilters;
309 void QDeclarativeFolderListModel::setNameFilters(const QStringList &filters)
311 d->nameFilters = filters;
312 d->model.setNameFilters(d->nameFilters);
315 void QDeclarativeFolderListModel::classBegin()
319 void QDeclarativeFolderListModel::componentComplete()
321 if (!d->folder.isValid() || d->folder.toLocalFile().isEmpty() || !QDir().exists(d->folder.toLocalFile()))
322 setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
324 if (!d->folderIndex.isValid())
325 QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
329 \qmlproperty enumeration FolderListModel::sortField
331 The \a sortField property contains field to use for sorting. sortField
334 \o Unsorted - no sorting is applied. The order is system default.
335 \o Name - sort by filename
336 \o Time - sort by time modified
337 \o Size - sort by file size
338 \o Type - sort by file type (extension)
343 QDeclarativeFolderListModel::SortField QDeclarativeFolderListModel::sortField() const
348 void QDeclarativeFolderListModel::setSortField(SortField field)
350 if (field != d->sortField) {
351 d->sortField = field;
357 \qmlproperty bool FolderListModel::sortReversed
359 If set to true, reverses the sort order. The default is false.
363 bool QDeclarativeFolderListModel::sortReversed() const
365 return d->sortReversed;
368 void QDeclarativeFolderListModel::setSortReversed(bool rev)
370 if (rev != d->sortReversed) {
371 d->sortReversed = rev;
377 \qmlmethod bool FolderListModel::isFolder(int index)
379 Returns true if the entry \a index is a folder; otherwise
382 bool QDeclarativeFolderListModel::isFolder(int index) const
385 QModelIndex idx = d->model.index(index, 0, d->folderIndex);
387 return d->model.isDir(idx);
392 void QDeclarativeFolderListModel::refresh()
394 if (d->insideRefresh)
396 d->insideRefresh = true;
398 d->folderIndex = QModelIndex();
400 emit beginRemoveRows(QModelIndex(), 0, d->count-1);
402 emit endRemoveRows();
405 d->folderIndex = d->model.index(d->folder.toLocalFile());
406 int newcount = d->model.rowCount(d->folderIndex);
408 emit beginInsertRows(QModelIndex(), 0, newcount-1);
410 emit endInsertRows();
413 d->insideRefresh = false; // finished refreshing.
416 void QDeclarativeFolderListModel::inserted(const QModelIndex &index, int start, int end)
418 if (index == d->folderIndex) {
419 emit beginInsertRows(QModelIndex(), start, end);
420 d->count = d->model.rowCount(d->folderIndex);
421 emit endInsertRows();
425 void QDeclarativeFolderListModel::removed(const QModelIndex &index, int start, int end)
427 if (index == d->folderIndex) {
428 emit beginRemoveRows(QModelIndex(), start, end);
429 d->count = d->model.rowCount(d->folderIndex);
430 emit endRemoveRows();
434 void QDeclarativeFolderListModel::handleDataChanged(const QModelIndex &start, const QModelIndex &end)
436 if (start.parent() == d->folderIndex)
437 emit dataChanged(index(start.row(),0), index(end.row(),0));
441 \qmlproperty bool FolderListModel::showDirs
443 If true, directories are included in the model; otherwise only files
446 By default, this property is true.
448 Note that the nameFilters are not applied to directories.
452 bool QDeclarativeFolderListModel::showDirs() const
454 return d->model.filter() & QDir::AllDirs;
457 void QDeclarativeFolderListModel::setShowDirs(bool on)
459 if (!(d->model.filter() & QDir::AllDirs) == !on)
463 d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives);
466 d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives));
471 \qmlproperty bool FolderListModel::showDotAndDotDot
473 If true, the "." and ".." directories are included in the model; otherwise
476 By default, this property is false.
480 bool QDeclarativeFolderListModel::showDotAndDotDot() const
482 return !(d->model.filter() & QDir::NoDotAndDotDot);
485 void QDeclarativeFolderListModel::setShowDotAndDotDot(bool on)
487 if (!(d->model.filter() & QDir::NoDotAndDotDot) == on)
491 d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot);
494 d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot);
499 \qmlproperty bool FolderListModel::showOnlyReadable
501 If true, only readable files and directories are shown; otherwise all files
502 and directories are shown.
504 By default, this property is false.
508 bool QDeclarativeFolderListModel::showOnlyReadable() const
510 return d->model.filter() & QDir::Readable;
513 void QDeclarativeFolderListModel::setShowOnlyReadable(bool on)
515 if (!(d->model.filter() & QDir::Readable) == !on)
518 d->showOnlyReadable = true;
519 d->model.setFilter(d->model.filter() | QDir::Readable);
521 d->showOnlyReadable = false;
522 d->model.setFilter(d->model.filter() & ~QDir::Readable);
529 #endif // QT_NO_DIRMODEL