diff options
Diffstat (limited to 'src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp')
-rw-r--r-- | src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp new file mode 100644 index 0000000..9cf81ca --- /dev/null +++ b/src/imports/folderlistmodel/qdeclarativefolderlistmodel.cpp @@ -0,0 +1,403 @@ +/**************************************************************************** +** +** 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 <QDirModel> +#include <QDebug> +#include <qdeclarativecontext.h> + +#ifndef QT_NO_DIRMODEL + +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<int, QByteArray> 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<string> 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 + +#endif // QT_NO_DIRMODEL |