summaryrefslogtreecommitdiffstats
path: root/src/widgets/dialogs/qfilesystemmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/dialogs/qfilesystemmodel.cpp')
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp224
1 files changed, 69 insertions, 155 deletions
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 4859231d95..d23737f130 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -39,6 +39,7 @@
#include <qdebug.h>
#include <qmessagebox.h>
#include <qapplication.h>
+#include <QtCore/qcollator.h>
#include <algorithm>
@@ -154,6 +155,11 @@ QT_BEGIN_NAMESPACE
Returns the QFileInfo for the item stored in the model under the given
\a index.
*/
+QFileInfo QFileSystemModel::fileInfo(const QModelIndex &index) const
+{
+ Q_D(const QFileSystemModel);
+ return d->node(index)->fileInfo();
+}
/*!
\fn void QFileSystemModel::rootPathChanged(const QString &newPath);
@@ -192,13 +198,14 @@ QT_BEGIN_NAMESPACE
bool QFileSystemModel::remove(const QModelIndex &aindex)
{
const QString path = filePath(aindex);
+ const bool success = QFileInfo(path).isFile() ? QFile::remove(path) : QDir(path).removeRecursively();
#ifndef QT_NO_FILESYSTEMWATCHER
- QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
- d->fileInfoGatherer.removePath(path);
+ if (success) {
+ QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
+ d->fileInfoGatherer.removePath(path);
+ }
#endif
- if (QFileInfo(path).isFile())
- return QFile::remove(path);
- return QDir(path).removeRecursively();
+ return success;
}
/*!
@@ -243,7 +250,7 @@ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &pare
Q_ASSERT(parentNode);
// now get the internal pointer for the index
- QString childName = parentNode->visibleChildren[d->translateVisibleLocation(parentNode, row)];
+ const QString &childName = parentNode->visibleChildren.at(d->translateVisibleLocation(parentNode, row));
const QFileSystemModelPrivate::QFileSystemNode *indexNode = parentNode->children.value(childName);
Q_ASSERT(indexNode);
@@ -259,10 +266,7 @@ QModelIndex QFileSystemModel::index(const QString &path, int column) const
{
Q_D(const QFileSystemModel);
QFileSystemModelPrivate::QFileSystemNode *node = d->node(path, false);
- QModelIndex idx = d->index(node);
- if (idx.column() != column)
- idx = idx.sibling(idx.row(), column);
- return idx;
+ return d->index(node, column);
}
/*!
@@ -375,7 +379,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
{
- if (!pathElements.at(0).contains(QLatin1String(":"))) {
+ if (!pathElements.at(0).contains(QLatin1Char(':'))) {
QString rootPath = QDir(longPath).rootPath();
pathElements.prepend(rootPath);
}
@@ -476,7 +480,7 @@ void QFileSystemModel::timerEvent(QTimerEvent *event)
d->fileInfoGatherer.fetchExtendedInformation(d->toFetch.at(i).dir,
QStringList(d->toFetch.at(i).file));
} else {
- // qDebug() << "yah!, you saved a little gerbil soul";
+ // qDebug("yah!, you saved a little gerbil soul");
}
}
#endif
@@ -562,7 +566,7 @@ QModelIndex QFileSystemModel::parent(const QModelIndex &index) const
return the index for node
*/
-QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileSystemNode *node) const
+QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileSystemNode *node, int column) const
{
Q_Q(const QFileSystemModel);
QFileSystemModelPrivate::QFileSystemNode *parentNode = (node ? node->parent : 0);
@@ -575,7 +579,7 @@ QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileS
return QModelIndex();
int visualRow = translateVisibleLocation(parentNode, parentNode->visibleLocation(node->fileName));
- return q->createIndex(visualRow, 0, const_cast<QFileSystemNode*>(node));
+ return q->createIndex(visualRow, column, const_cast<QFileSystemNode*>(node));
}
/*!
@@ -643,7 +647,7 @@ int QFileSystemModel::rowCount(const QModelIndex &parent) const
*/
int QFileSystemModel::columnCount(const QModelIndex &parent) const
{
- return (parent.column() > 0) ? 0 : 4;
+ return (parent.column() > 0) ? 0 : QFileSystemModelPrivate::NumColumns;
}
/*!
@@ -799,8 +803,7 @@ QString QFileSystemModelPrivate::name(const QModelIndex &index) const
#endif
!resolvedSymLinks.isEmpty() && dirNode->isSymLink(/* ignoreNtfsSymLinks = */ true)) {
QString fullPath = QDir::fromNativeSeparators(filePath(index));
- if (resolvedSymLinks.contains(fullPath))
- return resolvedSymLinks[fullPath];
+ return resolvedSymLinks.value(fullPath, dirNode->fileName);
}
return dirNode->fileName;
}
@@ -978,84 +981,6 @@ void QFileSystemModelPrivate::_q_performDelayedSort()
q->sort(sortColumn, sortOrder);
}
-static inline QChar getNextChar(const QString &s, int location)
-{
- return (location < s.length()) ? s.at(location) : QChar();
-}
-
-/*!
- Natural number sort, skips spaces.
-
- Examples:
- 1, 2, 10, 55, 100
- 01.jpg, 2.jpg, 10.jpg
-
- Note on the algorithm:
- Only as many characters as necessary are looked at and at most they all
- are looked at once.
-
- Slower then QString::compare() (of course)
- */
-int QFileSystemModelPrivate::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
-{
- for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) {
- // skip spaces, tabs and 0's
- QChar c1 = getNextChar(s1, l1);
- while (c1.isSpace())
- c1 = getNextChar(s1, ++l1);
- QChar c2 = getNextChar(s2, l2);
- while (c2.isSpace())
- c2 = getNextChar(s2, ++l2);
-
- if (c1.isDigit() && c2.isDigit()) {
- while (c1.digitValue() == 0)
- c1 = getNextChar(s1, ++l1);
- while (c2.digitValue() == 0)
- c2 = getNextChar(s2, ++l2);
-
- int lookAheadLocation1 = l1;
- int lookAheadLocation2 = l2;
- int currentReturnValue = 0;
- // find the last digit, setting currentReturnValue as we go if it isn't equal
- for (
- QChar lookAhead1 = c1, lookAhead2 = c2;
- (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length());
- lookAhead1 = getNextChar(s1, ++lookAheadLocation1),
- lookAhead2 = getNextChar(s2, ++lookAheadLocation2)
- ) {
- bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit();
- bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit();
- if (!is1ADigit && !is2ADigit)
- break;
- if (!is1ADigit)
- return -1;
- if (!is2ADigit)
- return 1;
- if (currentReturnValue == 0) {
- if (lookAhead1 < lookAhead2) {
- currentReturnValue = -1;
- } else if (lookAhead1 > lookAhead2) {
- currentReturnValue = 1;
- }
- }
- }
- if (currentReturnValue != 0)
- return currentReturnValue;
- }
-
- if (cs == Qt::CaseInsensitive) {
- if (!c1.isLower()) c1 = c1.toLower();
- if (!c2.isLower()) c2 = c2.toLower();
- }
- int r = QString::localeAwareCompare(c1, c2);
- if (r < 0)
- return -1;
- if (r > 0)
- return 1;
- }
- // The two strings are the same (02 == 2) so fall back to the normal sort
- return QString::compare(s1, s2, cs);
-}
/*
\internal
@@ -1064,7 +989,11 @@ int QFileSystemModelPrivate::naturalCompare(const QString &s1, const QString &s2
class QFileSystemModelSorter
{
public:
- inline QFileSystemModelSorter(int column) : sortColumn(column) {}
+ inline QFileSystemModelSorter(int column) : sortColumn(column)
+ {
+ naturalCompare.setNumericMode(true);
+ naturalCompare.setCaseSensitivity(Qt::CaseInsensitive);
+ }
bool compareNodes(const QFileSystemModelPrivate::QFileSystemNode *l,
const QFileSystemModelPrivate::QFileSystemNode *r) const
@@ -1078,8 +1007,7 @@ public:
if (left ^ right)
return left;
#endif
- return QFileSystemModelPrivate::naturalCompare(l->fileName,
- r->fileName, Qt::CaseInsensitive) < 0;
+ return naturalCompare.compare(l->fileName, r->fileName) < 0;
}
case 1:
{
@@ -1091,22 +1019,22 @@ public:
qint64 sizeDifference = l->size() - r->size();
if (sizeDifference == 0)
- return QFileSystemModelPrivate::naturalCompare(l->fileName, r->fileName, Qt::CaseInsensitive) < 0;
+ return naturalCompare.compare(l->fileName, r->fileName) < 0;
return sizeDifference < 0;
}
case 2:
{
- int compare = QString::localeAwareCompare(l->type(), r->type());
+ int compare = naturalCompare.compare(l->type(), r->type());
if (compare == 0)
- return QFileSystemModelPrivate::naturalCompare(l->fileName, r->fileName, Qt::CaseInsensitive) < 0;
+ return naturalCompare.compare(l->fileName, r->fileName) < 0;
return compare < 0;
}
case 3:
{
if (l->lastModified() == r->lastModified())
- return QFileSystemModelPrivate::naturalCompare(l->fileName, r->fileName, Qt::CaseInsensitive) < 0;
+ return naturalCompare.compare(l->fileName, r->fileName) < 0;
return l->lastModified() < r->lastModified();
}
@@ -1115,14 +1043,15 @@ public:
return false;
}
- bool operator()(const QPair<QFileSystemModelPrivate::QFileSystemNode*, int> &l,
- const QPair<QFileSystemModelPrivate::QFileSystemNode*, int> &r) const
+ bool operator()(const QFileSystemModelPrivate::QFileSystemNode *l,
+ const QFileSystemModelPrivate::QFileSystemNode *r) const
{
- return compareNodes(l.first, r.first);
+ return compareNodes(l, r);
}
private:
+ QCollator naturalCompare;
int sortColumn;
};
@@ -1138,16 +1067,14 @@ void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent
if (indexNode->children.count() == 0)
return;
- QList<QPair<QFileSystemModelPrivate::QFileSystemNode*, int> > values;
+ QVector<QFileSystemModelPrivate::QFileSystemNode*> values;
QHash<QString, QFileSystemNode *>::const_iterator iterator;
- int i = 0;
for(iterator = indexNode->children.constBegin() ; iterator != indexNode->children.constEnd() ; ++iterator) {
if (filtersAcceptsNode(iterator.value())) {
- values.append(QPair<QFileSystemModelPrivate::QFileSystemNode*, int>((iterator.value()), i));
+ values.append(iterator.value());
} else {
iterator.value()->isVisible = false;
}
- i++;
}
QFileSystemModelSorter ms(column);
std::sort(values.begin(), values.end(), ms);
@@ -1155,9 +1082,11 @@ void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent
indexNode->visibleChildren.clear();
//No more dirty item we reset our internal dirty index
indexNode->dirtyChildrenIndex = -1;
- for (int i = 0; i < values.count(); ++i) {
- indexNode->visibleChildren.append(values.at(i).first->fileName);
- values.at(i).first->isVisible = true;
+ const int numValues = values.count();
+ indexNode->visibleChildren.reserve(numValues);
+ for (int i = 0; i < numValues; ++i) {
+ indexNode->visibleChildren.append(values.at(i)->fileName);
+ values.at(i)->isVisible = true;
}
if (!disableRecursiveSort) {
@@ -1182,9 +1111,12 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order)
emit layoutAboutToBeChanged();
QModelIndexList oldList = persistentIndexList();
- QList<QPair<QFileSystemModelPrivate::QFileSystemNode*, int> > oldNodes;
- for (int i = 0; i < oldList.count(); ++i) {
- QPair<QFileSystemModelPrivate::QFileSystemNode*, int> pair(d->node(oldList.at(i)), oldList.at(i).column());
+ QVector<QPair<QFileSystemModelPrivate::QFileSystemNode*, int> > oldNodes;
+ const int nodeCount = oldList.count();
+ oldNodes.reserve(nodeCount);
+ for (int i = 0; i < nodeCount; ++i) {
+ const QModelIndex &oldNode = oldList.at(i);
+ QPair<QFileSystemModelPrivate::QFileSystemNode*, int> pair(d->node(oldNode), oldNode.column());
oldNodes.append(pair);
}
@@ -1197,10 +1129,11 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order)
d->sortOrder = order;
QModelIndexList newList;
- for (int i = 0; i < oldNodes.count(); ++i) {
- QModelIndex idx = d->index(oldNodes.at(i).first);
- idx = idx.sibling(idx.row(), oldNodes.at(i).second);
- newList.append(idx);
+ const int numOldNodes = oldNodes.size();
+ newList.reserve(numOldNodes);
+ for (int i = 0; i < numOldNodes; ++i) {
+ const QPair<QFileSystemModelPrivate::QFileSystemNode*, int> &oldNode = oldNodes.at(i);
+ newList.append(d->index(oldNode.first, oldNode.second));
}
changePersistentIndexList(oldList, newList);
emit layoutChanged();
@@ -1648,7 +1581,9 @@ QStringList QFileSystemModel::nameFilters() const
Q_D(const QFileSystemModel);
QStringList filters;
#ifndef QT_NO_REGEXP
- for (int i = 0; i < d->nameFilters.size(); ++i) {
+ const int numNameFilters = d->nameFilters.size();
+ filters.reserve(numNameFilters);
+ for (int i = 0; i < numNameFilters; ++i) {
filters << d->nameFilters.at(i).pattern();
}
#endif
@@ -1673,11 +1608,14 @@ bool QFileSystemModel::event(QEvent *event)
bool QFileSystemModel::rmdir(const QModelIndex &aindex)
{
QString path = filePath(aindex);
+ const bool success = QDir().rmdir(path);
#ifndef QT_NO_FILESYSTEMWATCHER
- QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
- d->fileInfoGatherer.removePath(path);
+ if (success) {
+ QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
+ d->fileInfoGatherer.removePath(path);
+ }
#endif
- return QDir().rmdir(path);
+ return success;
}
/*!
@@ -1765,26 +1703,6 @@ void QFileSystemModelPrivate::removeNode(QFileSystemModelPrivate::QFileSystemNod
q->endRemoveRows();
}
-/*
- \internal
- Helper functor used by addVisibleFiles()
-*/
-class QFileSystemModelVisibleFinder
-{
-public:
- inline QFileSystemModelVisibleFinder(QFileSystemModelPrivate::QFileSystemNode *node, QFileSystemModelSorter *sorter) : parentNode(node), sorter(sorter) {}
-
- bool operator()(const QString &, QString r) const
- {
- return sorter->compareNodes(parentNode->children.value(name), parentNode->children.value(r));
- }
-
- QString name;
-private:
- QFileSystemModelPrivate::QFileSystemNode *parentNode;
- QFileSystemModelSorter *sorter;
-};
-
/*!
\internal
@@ -1806,9 +1724,9 @@ void QFileSystemModelPrivate::addVisibleFiles(QFileSystemNode *parentNode, const
parentNode->dirtyChildrenIndex = parentNode->visibleChildren.count();
for (int i = 0; i < newFiles.count(); ++i) {
- parentNode->visibleChildren.append(newFiles.at(i));
- parentNode->children[newFiles.at(i)]->isVisible = true;
- }
+ parentNode->visibleChildren.append(newFiles.at(i));
+ parentNode->children.value(newFiles.at(i))->isVisible = true;
+ }
if (!indexHidden)
q->endInsertRows();
}
@@ -1830,7 +1748,7 @@ void QFileSystemModelPrivate::removeVisibleFile(QFileSystemNode *parentNode, int
if (!indexHidden)
q->beginRemoveRows(parent, translateVisibleLocation(parentNode, vLocation),
translateVisibleLocation(parentNode, vLocation));
- parentNode->children[parentNode->visibleChildren.at(vLocation)]->isVisible = false;
+ parentNode->children.value(parentNode->visibleChildren.at(vLocation))->isVisible = false;
parentNode->visibleChildren.removeAt(vLocation);
if (!indexHidden)
q->endRemoveRows();
@@ -1842,7 +1760,7 @@ void QFileSystemModelPrivate::removeVisibleFile(QFileSystemNode *parentNode, int
The thread has received new information about files,
update and emit dataChanged if it has actually changed.
*/
-void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QList<QPair<QString, QFileInfo> > &updates)
+void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QVector<QPair<QString, QFileInfo> > &updates)
{
#ifndef QT_NO_FILESYSTEMWATCHER
Q_Q(QFileSystemModel);
@@ -1873,10 +1791,6 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QL
node->fileName = fileName;
}
- if (info.size() == -1 && !info.isSymLink()) {
- removeNode(parentNode, fileName);
- continue;
- }
if (*node != info ) {
node->populate(info);
bypassFilters.remove(node);
@@ -1961,12 +1875,12 @@ void QFileSystemModelPrivate::_q_resolvedName(const QString &fileName, const QSt
void QFileSystemModelPrivate::init()
{
Q_Q(QFileSystemModel);
- qRegisterMetaType<QList<QPair<QString,QFileInfo> > >();
+ qRegisterMetaType<QVector<QPair<QString,QFileInfo> > >();
#ifndef QT_NO_FILESYSTEMWATCHER
q->connect(&fileInfoGatherer, SIGNAL(newListOfFiles(QString,QStringList)),
q, SLOT(_q_directoryChanged(QString,QStringList)));
- q->connect(&fileInfoGatherer, SIGNAL(updates(QString,QList<QPair<QString,QFileInfo> >)),
- q, SLOT(_q_fileSystemChanged(QString,QList<QPair<QString,QFileInfo> >)));
+ q->connect(&fileInfoGatherer, SIGNAL(updates(QString,QVector<QPair<QString,QFileInfo> >)),
+ q, SLOT(_q_fileSystemChanged(QString,QVector<QPair<QString,QFileInfo> >)));
q->connect(&fileInfoGatherer, SIGNAL(nameResolved(QString,QString)),
q, SLOT(_q_resolvedName(QString,QString)));
q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)),