1 /****************************************************************************
3 ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
5 ** This file is part of the QtGui module of the Qt Toolkit.
7 ** This file may be used under the terms of the GNU General Public
8 ** License version 2.0 as published by the Free Software Foundation
9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 ** this file. Please review the following information to ensure GNU
11 ** General Public Licensing requirements will be met:
12 ** http://www.trolltech.com/products/qt/opensource.html
14 ** If you are unsure which license is appropriate for your use, please
15 ** review the following information:
16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 ** sales department at sales@trolltech.com.
19 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 ****************************************************************************/
24 #ifndef QFILESYSTEMMODEL_H
25 #define QFILESYSTEMMODEL_H
27 #include <QtCore/qabstractitemmodel.h>
28 #include <QtCore/qpair.h>
29 #include <QtCore/qdir.h>
30 #include <QtGui/qicon.h>
33 class ExtendedInformation
;
34 class QFileSystemModelPrivate
;
35 class QFileSystemModel
;
36 class QFileIconProvider
;
39 #ifndef QFLATDIRMODEL_P_H
40 #define QFLATDIRMODEL_P_H
42 #include <qabstractitemmodel.h>
43 #include "qfileinfogatherer_p.h"
46 #include <qfileinfo.h>
50 class Q_AUTOTEST_EXPORT QFileSystemModelPrivate
57 QFileSystemNode(const QString
&filename
= QString(), QFileSystemNode
*p
=0)
58 : fileName(filename
), populatedChildren(false), parent(p
), info(0) {}
59 ~QFileSystemNode() { delete info
; }
63 inline qint64
size() const { if (info
&& !info
->isDir()) return info
->size
; return 0; }
64 inline QString
type() const { if (info
) return info
->displayType
; return QLatin1String(""); }
65 inline QDateTime
lastModified() const { if (info
) return info
->lastModified
; return QDateTime(); }
66 inline QFile::Permissions
permissions() const { if (info
) return info
->permissions
; return 0; }
67 inline bool isReadable() const { return (permissions() & QFile::ReadUser
); }
68 inline bool isWritable() const { return (permissions() & QFile::WriteUser
); }
69 inline bool isExecutable() const { return (permissions() & QFile::ExeUser
); }
70 inline bool isDir() const {
73 if (children
.count() > 0)
77 inline bool isFile() const { if (info
) return info
->isFile(); return true; }
78 inline bool isSystem() const { if (info
) return info
->isSystem(); return true; }
79 inline bool isHidden() const { if (info
) return info
->isHidden
; return false; }
80 inline bool isSymLink() const { if (info
) return info
->isSymLink
; return false; }
81 inline bool caseSensitive() const { if (info
) return info
->caseSensitive
; return true; }
82 inline QIcon
icon() const { if (info
) return info
->icon
; return QIcon(); }
84 inline bool operator <(const QFileSystemNode
&node
) const {
86 return fileName
< node
.fileName
;
87 return fileName
.toLower() < node
.fileName
.toLower();
89 inline bool operator >(const QString
&name
) const {
91 return fileName
> name
;
92 return fileName
.toLower() > name
.toLower();
94 inline bool operator <(const QString
&name
) const {
96 return fileName
< name
;
97 return fileName
.toLower() < name
.toLower();
99 inline bool operator !=(const QExtendedInformation
&fileInfo
) const {
100 return !operator==(fileInfo
);
102 bool operator ==(const QString
&name
) const {
104 return fileName
== name
;
105 return fileName
.toLower() == name
.toLower();
107 bool operator ==(const QExtendedInformation
&fileInfo
) const {
108 return info
&& (*info
== fileInfo
);
111 inline bool hasInformation() const { return info
!= 0; }
113 void populate(const QExtendedInformation
&fileInfo
) {
115 info
= new QExtendedInformation();
119 // children shouldn't normally be accessed directly, use node()
120 inline int visibleLocation(int childRow
) {
121 return visibleChildren
.indexOf(childRow
);
123 bool populatedChildren
;
124 QList
<QFileSystemNode
> children
;
125 QList
<int> visibleChildren
;
126 QFileSystemNode
*parent
;
129 QExtendedInformation
*info
;
133 QFileSystemModelPrivate() :
136 sortOrder(Qt::AscendingOrder
),
138 filters(QDir::AllEntries
| QDir::NoDotAndDotDot
| QDir::AllDirs
),
139 nameFilterDisables(true) // false on windows, true on mac and unix
141 delayedSortTimer
.setSingleShot(true);
148 Return true if index which is owned by node is hidden by the filter.
150 inline bool isHiddenByFilter(QFileSystemNode
*indexNode
, const QModelIndex
&index
) const
152 return (indexNode
!= &root
&& !index
.isValid());
154 QFileSystemNode
*node(const QModelIndex
&index
) const;
155 QFileSystemNode
*node(const QString
&path
, bool fetch
= true) const;
156 inline QModelIndex
index(const QString
&path
) { return index(node(path
)); }
157 QModelIndex
index(const QFileSystemNode
*node
) const;
158 bool filtersAcceptsNode(const QFileSystemNode
*node
) const;
159 bool passNameFilters(const QFileSystemNode
*node
) const;
160 void removeNode(QFileSystemNode
*parentNode
, int itemLocation
);
161 int addNode(QFileSystemNode
*parentNode
, const QString
&fileName
);
162 void addVisibleFiles(QFileSystemNode
*parentNode
, const QStringList
&newFiles
);
163 void removeVisibleFile(QFileSystemNode
*parentNode
, int visibleLocation
);
164 void sortChildren(int column
, Qt::SortOrder order
, const QModelIndex
&parent
);
166 inline int translateVisibleLocation(QFileSystemNode
*parent
, int row
) const {
167 return (sortOrder
== Qt::AscendingOrder
) ? row
: parent
->visibleChildren
.count() - row
- 1;
170 inline static QString
myComputer() {
171 // ### TODO We should query the system to find out what the string should be
172 // XP == "My Computer",
173 // Vista == "Computer",
174 // OS X == "Computer" (sometime user generated) "Benjamin's PowerBook G4"
176 return ("My Computer");
182 inline void delayedSort() {
183 if (!delayedSortTimer
.isActive())
184 delayedSortTimer
.start(0);
187 static bool caseInsensitiveLessThan(const QString
&s1
, const QString
&s2
)
189 return s1
.toLower() < s2
.toLower();
192 static bool nodeCaseInsensitiveLessThan(const QFileSystemModelPrivate::QFileSystemNode
&s1
, const QFileSystemModelPrivate::QFileSystemNode
&s2
)
194 return s1
.fileName
.toLower() < s2
.fileName
.toLower();
197 inline int findChild(const QFileSystemNode
*parent
, const QFileSystemNode
&node
) const {
198 QList
<QFileSystemNode
>::const_iterator iterator
;
199 if (parent
->caseSensitive())
200 iterator
= (qBinaryFind(parent
->children
.begin(), parent
->children
.end(), node
));
202 iterator
= (qBinaryFind(parent
->children
.begin(), parent
->children
.end(), node
, nodeCaseInsensitiveLessThan
));
203 if (iterator
== parent
->children
.end())
205 int location
= (iterator
- parent
->children
.begin());
206 Q_ASSERT(location
< parent
->children
.count());
210 inline int findWhereToInsertChild(const QFileSystemNode
*parent
, const QFileSystemNode
*node
) const {
211 QList
<QFileSystemNode
>::const_iterator iterator
;
212 if (parent
->caseSensitive()) {
213 iterator
= (qUpperBound(parent
->children
.begin(), parent
->children
.end(), *node
));
215 iterator
= (qUpperBound(parent
->children
.begin(), parent
->children
.end(), *node
, QFileSystemModelPrivate::nodeCaseInsensitiveLessThan
));
216 return (iterator
- parent
->children
.begin());
219 QIcon
icon(const QModelIndex
&index
) const;
220 QString
name(const QModelIndex
&index
) const;
221 QString
size(const QModelIndex
&index
) const;
222 static QString
size(qint64 bytes
);
223 QString
type(const QModelIndex
&index
) const;
224 QString
time(const QModelIndex
&index
) const;
226 void _q_directoryChanged(const QString
&directory
, const QStringList
&list
);
227 void _q_performDelayedSort();
228 void _q_fileSystemChanged(const QString
&path
, const QList
<QPair
<QString
, QExtendedInformation
> > &);
229 void _q_resolvedName(const QString
&fileName
, const QString
&resolvedName
);
231 static int naturalCompare(const QString
&s1
, const QString
&s2
, Qt::CaseSensitivity cs
);
234 QFileInfoGatherer fileInfoGatherer
;
235 QTimer delayedSortTimer
;
238 Qt::SortOrder sortOrder
;
240 QDir::Filters filters
;
241 QList
<const QFileSystemNode
*> bypassFilters
;
242 bool nameFilterDisables
;
244 QList
<QRegExp
> nameFilters
;
246 // ### resolvedSymLinks goes away in Qt5
247 QHash
<QString
, QString
> resolvedSymLinks
;
249 QFileSystemNode root
;
251 QBasicTimer fetchingTimer
;
255 const QFileSystemNode
*node
;
257 QList
<Fetching
> toFetch
;
266 class Q_AUTOTEST_EXPORT QFileSystemModel
: public QAbstractItemModel
268 friend class QFileSystemModelPrivate
;
271 Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks
)
272 Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly
)
273 Q_PROPERTY(bool nameFilterDisables READ nameFilterDisables WRITE setNameFilterDisables
)
276 void rootPathChanged(const QString
&newPath
);
280 FileIconRole
= Qt::DecorationRole
,
281 FilePathRole
= Qt::UserRole
+ 1,
285 explicit QFileSystemModel(QObject
*parent
= 0);
288 QModelIndex
index(int row
, int column
, const QModelIndex
&parent
= QModelIndex()) const;
289 QModelIndex
index(const QString
&path
, int column
= 0) const;
290 QModelIndex
parent(const QModelIndex
&child
) const;
291 bool hasChildren(const QModelIndex
&parent
= QModelIndex()) const;
292 bool canFetchMore(const QModelIndex
&parent
) const;
293 void fetchMore(const QModelIndex
&parent
);
295 int rowCount(const QModelIndex
&parent
= QModelIndex()) const;
296 int columnCount(const QModelIndex
&parent
= QModelIndex()) const;
298 QVariant
myComputer(int role
= Qt::DisplayRole
) const;
299 QVariant
data(const QModelIndex
&index
, int role
= Qt::DisplayRole
) const;
300 bool setData(const QModelIndex
&index
, const QVariant
&value
, int role
= Qt::EditRole
);
302 QVariant
headerData(int section
, Qt::Orientation orientation
, int role
= Qt::DisplayRole
) const;
304 Qt::ItemFlags
flags(const QModelIndex
&index
) const;
306 void sort(int column
, Qt::SortOrder order
= Qt::AscendingOrder
);
308 QStringList
mimeTypes() const;
309 QMimeData
*mimeData(const QModelIndexList
&indexes
) const;
310 bool dropMimeData(const QMimeData
*data
, Qt::DropAction action
,
311 int row
, int column
, const QModelIndex
&parent
);
312 Qt::DropActions
supportedDropActions() const;
314 // QFileSystemModel specific API
315 QModelIndex
setRootPath(const QString
&path
);
316 QString
rootPath() const;
317 QDir
rootDirectory() const;
319 void setIconProvider(QFileIconProvider
*provider
);
320 QFileIconProvider
*iconProvider() const;
322 void setFilter(QDir::Filters filters
);
323 QDir::Filters
filter() const;
325 void setResolveSymlinks(bool enable
);
326 bool resolveSymlinks() const;
328 void setReadOnly(bool enable
);
329 bool isReadOnly() const;
331 void setNameFilterDisables(bool enable
);
332 bool nameFilterDisables() const;
334 void setNameFilters(const QStringList
&filters
);
335 QStringList
nameFilters() const;
337 QString
filePath(const QModelIndex
&index
) const;
338 bool isDir(const QModelIndex
&index
) const;
339 qint64
size(const QModelIndex
&index
) const;
340 QString
type(const QModelIndex
&index
) const;
341 QDateTime
lastModified(const QModelIndex
&index
) const;
343 QModelIndex
mkdir(const QModelIndex
&parent
, const QString
&name
);
344 inline bool rmdir(const QModelIndex
&index
) { QDir dir
; return dir
.rmdir(filePath(index
)); }
345 inline QString
fileName(const QModelIndex
&index
) const { return index
.data(Qt::DisplayRole
).toString(); }
346 inline QIcon
fileIcon(const QModelIndex
&index
) const { return qvariant_cast
<QIcon
>(index
.data(Qt::DecorationRole
)); }
347 QFile::Permissions
permissions(const QModelIndex
&index
) const;
348 inline QFileInfo
fileInfo(const QModelIndex
&index
) const { return QFileInfo(filePath(index
)); }
349 inline bool remove(const QModelIndex
&index
) { if (isDir(index
)) return rmdir(index
); else return QFile::remove(filePath(index
)); }
352 QFileSystemModel(QFileSystemModelPrivate
&, QObject
*parent
= 0);
353 void timerEvent(QTimerEvent
*event
);
356 QFileSystemModelPrivate
*d
;
357 Q_DISABLE_COPY(QFileSystemModel
)
359 Q_PRIVATE_SLOT(d
, void _q_directoryChanged(const QString
&directory
, const QStringList
&list
));
360 Q_PRIVATE_SLOT(d
, void _q_performDelayedSort());
361 Q_PRIVATE_SLOT(d
, void _q_fileSystemChanged(const QString
&path
, const QList
<QPair
<QString
, QExtendedInformation
> > &));
362 Q_PRIVATE_SLOT(d
, void _q_resolvedName(const QString
&fileName
, const QString
&resolvedName
));
365 #endif // QFILESYSTEMMODEL_H