only include Applications by default on OS X
[ambit.git] / src / qfilesystemmodel_p.h
blob038ebc390fc99278c1d96e647628cb959faa80d7
1 /****************************************************************************
2 **
3 ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
4 **
5 ** This file is part of the QtGui module of the Qt Toolkit.
6 **
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>
31 #include <qevent.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"
44 #include <qdir.h>
45 #include <qicon.h>
46 #include <qfileinfo.h>
47 #include <qtimer.h>
48 #include <qhash.h>
50 class Q_AUTOTEST_EXPORT QFileSystemModelPrivate
53 public:
54 class QFileSystemNode
56 public:
57 QFileSystemNode(const QString &filename = QString(), QFileSystemNode *p=0)
58 : fileName(filename), populatedChildren(false), parent(p), info(0) {}
59 ~QFileSystemNode() { delete info; }
61 QString fileName;
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 {
71 if (info)
72 return info->isDir();
73 if (children.count() > 0)
74 return true;
75 return false;
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 {
85 if (caseSensitive())
86 return fileName < node.fileName;
87 return fileName.toLower() < node.fileName.toLower();
89 inline bool operator >(const QString &name) const {
90 if (caseSensitive())
91 return fileName > name;
92 return fileName.toLower() > name.toLower();
94 inline bool operator <(const QString &name) const {
95 if (caseSensitive())
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 {
103 if (caseSensitive())
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) {
114 if (!info)
115 info = new QExtendedInformation();
116 (*info) = fileInfo;
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;
128 private:
129 QExtendedInformation *info;
133 QFileSystemModelPrivate() :
134 forceSort(true),
135 sortColumn(0),
136 sortOrder(Qt::AscendingOrder),
137 readOnly(true),
138 filters(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs),
139 nameFilterDisables(true) // false on windows, true on mac and unix
141 delayedSortTimer.setSingleShot(true);
144 void init();
146 \internal
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"
175 #ifdef Q_OS_WIN
176 return ("My Computer");
177 #else
178 return ("Computer");
179 #endif
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));
201 else
202 iterator = (qBinaryFind(parent->children.begin(), parent->children.end(), node, nodeCaseInsensitiveLessThan));
203 if (iterator == parent->children.end())
204 return -1;
205 int location = (iterator - parent->children.begin());
206 Q_ASSERT(location < parent->children.count());
207 return location;
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));
214 } else
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);
233 QDir rootDir;
234 QFileInfoGatherer fileInfoGatherer;
235 QTimer delayedSortTimer;
236 bool forceSort;
237 int sortColumn;
238 Qt::SortOrder sortOrder;
239 bool readOnly;
240 QDir::Filters filters;
241 QList<const QFileSystemNode*> bypassFilters;
242 bool nameFilterDisables;
243 #ifndef QT_NO_REGEXP
244 QList<QRegExp> nameFilters;
245 #endif
246 // ### resolvedSymLinks goes away in Qt5
247 QHash<QString, QString> resolvedSymLinks;
249 QFileSystemNode root;
251 QBasicTimer fetchingTimer;
252 struct Fetching {
253 QString dir;
254 QString file;
255 const QFileSystemNode *node;
257 QList<Fetching> toFetch;
259 QFileSystemModel *q;
262 #endif
266 class Q_AUTOTEST_EXPORT QFileSystemModel : public QAbstractItemModel
268 friend class QFileSystemModelPrivate;
270 Q_OBJECT
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)
275 Q_SIGNALS:
276 void rootPathChanged(const QString &newPath);
278 public:
279 enum Roles {
280 FileIconRole = Qt::DecorationRole,
281 FilePathRole = Qt::UserRole + 1,
282 FileNameRole
285 explicit QFileSystemModel(QObject *parent = 0);
286 ~QFileSystemModel();
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)); }
351 protected:
352 QFileSystemModel(QFileSystemModelPrivate &, QObject *parent = 0);
353 void timerEvent(QTimerEvent *event);
355 private:
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