summaryrefslogtreecommitdiffstats
path: root/src/gui/itemmodels
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/itemmodels')
-rw-r--r--src/gui/itemmodels/qfileinfogatherer.cpp193
-rw-r--r--src/gui/itemmodels/qfileinfogatherer_p.h61
-rw-r--r--src/gui/itemmodels/qfilesystemmodel.cpp451
-rw-r--r--src/gui/itemmodels/qfilesystemmodel.h54
-rw-r--r--src/gui/itemmodels/qfilesystemmodel_p.h99
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.cpp173
-rw-r--r--src/gui/itemmodels/qstandarditemmodel.h60
-rw-r--r--src/gui/itemmodels/qstandarditemmodel_p.h52
8 files changed, 536 insertions, 607 deletions
diff --git a/src/gui/itemmodels/qfileinfogatherer.cpp b/src/gui/itemmodels/qfileinfogatherer.cpp
index bd368e945c..41fb0a0db5 100644
--- a/src/gui/itemmodels/qfileinfogatherer.cpp
+++ b/src/gui/itemmodels/qfileinfogatherer.cpp
@@ -1,45 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfileinfogatherer_p.h"
+#include <qcoreapplication.h>
#include <qdebug.h>
-#include <qdiriterator.h>
+#include <qdirlisting.h>
+#include <private/qabstractfileiconprovider_p.h>
#include <private/qfileinfo_p.h>
#ifndef Q_OS_WIN
# include <unistd.h>
@@ -51,8 +17,10 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
#ifdef QT_BUILD_INTERNAL
-static QBasicAtomicInt fetchedRoot = Q_BASIC_ATOMIC_INITIALIZER(false);
+Q_CONSTINIT static QBasicAtomicInt fetchedRoot = Q_BASIC_ATOMIC_INITIALIZER(false);
Q_AUTOTEST_EXPORT void qt_test_resetFetchedRoot()
{
fetchedRoot.storeRelaxed(false);
@@ -68,9 +36,9 @@ static QString translateDriveName(const QFileInfo &drive)
{
QString driveName = drive.absoluteFilePath();
#ifdef Q_OS_WIN
- if (driveName.startsWith(QLatin1Char('/'))) // UNC host
+ if (driveName.startsWith(u'/')) // UNC host
return drive.fileName();
- if (driveName.endsWith(QLatin1Char('/')))
+ if (driveName.endsWith(u'/'))
driveName.chop(1);
#endif // Q_OS_WIN
return driveName;
@@ -91,11 +59,40 @@ QFileInfoGatherer::QFileInfoGatherer(QObject *parent)
*/
QFileInfoGatherer::~QFileInfoGatherer()
{
- abort.storeRelaxed(true);
+ requestAbort();
+ wait();
+}
+
+bool QFileInfoGatherer::event(QEvent *event)
+{
+ if (event->type() == QEvent::DeferredDelete && isRunning()) {
+ // We have been asked to shut down later but were blocked,
+ // so the owning QFileSystemModel proceeded with its shut-down
+ // and deferred the destruction of the gatherer.
+ // If we are still blocked now, then we have three bad options:
+ // terminate, wait forever (preventing the process from shutting down),
+ // or accept a memory leak.
+ requestAbort();
+ if (!wait(5000)) {
+ // If the application is shutting down, then we terminate.
+ // Otherwise assume that sooner or later the thread will finish,
+ // and we delete it then.
+ if (QCoreApplication::closingDown())
+ terminate();
+ else
+ connect(this, &QThread::finished, this, [this]{ delete this; });
+ return true;
+ }
+ }
+
+ return QThread::event(event);
+}
+
+void QFileInfoGatherer::requestAbort()
+{
+ requestInterruption();
QMutexLocker locker(&mutex);
condition.wakeAll();
- locker.unlock();
- wait();
}
void QFileInfoGatherer::setResolveSymlinks(bool enable)
@@ -117,7 +114,7 @@ void QFileInfoGatherer::driveRemoved()
const QFileInfoList driveInfoList = QDir::drives();
for (const QFileInfo &fi : driveInfoList)
drives.append(translateDriveName(fi));
- newListOfFiles(QString(), drives);
+ emit newListOfFiles(QString(), drives);
}
bool QFileInfoGatherer::resolveSymlinks() const
@@ -148,21 +145,24 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr
{
QMutexLocker locker(&mutex);
// See if we already have this dir/file in our queue
- int loc = this->path.lastIndexOf(path);
- while (loc > 0) {
- if (this->files.at(loc) == files) {
+ qsizetype loc = 0;
+ while ((loc = this->path.lastIndexOf(path, loc - 1)) != -1) {
+ if (this->files.at(loc) == files)
return;
- }
- loc = this->path.lastIndexOf(path, loc - 1);
}
+
+#if QT_CONFIG(thread)
this->path.push(path);
this->files.push(files);
condition.wakeAll();
+#else // !QT_CONFIG(thread)
+ getFileInfos(path, files);
+#endif // QT_CONFIG(thread)
#if QT_CONFIG(filesystemwatcher)
if (files.isEmpty()
&& !path.isEmpty()
- && !path.startsWith(QLatin1String("//")) /*don't watch UNC path*/) {
+ && !path.startsWith("//"_L1) /*don't watch UNC path*/) {
if (!watchedDirectories().contains(path))
watchPaths(QStringList(path));
}
@@ -176,8 +176,8 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr
*/
void QFileInfoGatherer::updateFile(const QString &filePath)
{
- QString dir = filePath.mid(0, filePath.lastIndexOf(QLatin1Char('/')));
- QString fileName = filePath.mid(dir.length() + 1);
+ QString dir = filePath.mid(0, filePath.lastIndexOf(u'/'));
+ QString fileName = filePath.mid(dir.size() + 1);
fetchExtendedInformation(dir, QStringList(fileName));
}
@@ -250,16 +250,23 @@ bool QFileInfoGatherer::isWatching() const
return result;
}
+/*! \internal
+
+ If \a v is \c false, the QFileSystemWatcher used internally will be deleted
+ and subsequent calls to watchPaths() will do nothing.
+
+ If \a v is \c true, subsequent calls to watchPaths() will add those paths to
+ the filesystem watcher; watchPaths() will initialize a QFileSystemWatcher if
+ one hasn't already been initialized.
+*/
void QFileInfoGatherer::setWatching(bool v)
{
#if QT_CONFIG(filesystemwatcher)
QMutexLocker locker(&mutex);
if (v != m_watching) {
- if (!v) {
- delete m_watcher;
- m_watcher = nullptr;
- }
m_watching = v;
+ if (!m_watching)
+ delete std::exchange(m_watcher, nullptr);
}
#else
Q_UNUSED(v);
@@ -311,17 +318,24 @@ void QFileInfoGatherer::list(const QString &directoryPath)
void QFileInfoGatherer::run()
{
forever {
+ // Disallow termination while we are holding a mutex or can be
+ // woken up cleanly.
+ setTerminationEnabled(false);
QMutexLocker locker(&mutex);
- while (!abort.loadRelaxed() && path.isEmpty())
+ while (!isInterruptionRequested() && path.isEmpty())
condition.wait(&mutex);
- if (abort.loadRelaxed())
+ if (isInterruptionRequested())
return;
- const QString thisPath = qAsConst(path).front();
+ const QString thisPath = std::as_const(path).front();
path.pop_front();
- const QStringList thisList = qAsConst(files).front();
+ const QStringList thisList = std::as_const(files).front();
files.pop_front();
locker.unlock();
+ // Some of the system APIs we call when gathering file infomration
+ // might hang (e.g. waiting for network), so we explicitly allow
+ // termination now.
+ setTerminationEnabled(true);
getFileInfos(thisPath, thisList);
}
}
@@ -329,8 +343,12 @@ void QFileInfoGatherer::run()
QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const
{
QExtendedInformation info(fileInfo);
- info.icon = m_iconProvider->icon(fileInfo);
- info.displayType = m_iconProvider->type(fileInfo);
+ if (m_iconProvider) {
+ info.icon = m_iconProvider->icon(fileInfo);
+ info.displayType = m_iconProvider->type(fileInfo);
+ } else {
+ info.displayType = QAbstractFileIconProviderPrivate::getFileType(fileInfo);
+ }
#if QT_CONFIG(filesystemwatcher)
// ### Not ready to listen all modifications by default
static const bool watchFiles = qEnvironmentVariableIsSet("QT_FILESYSTEMMODEL_WATCH_FILES");
@@ -370,21 +388,23 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
#ifdef QT_BUILD_INTERNAL
fetchedRoot.storeRelaxed(true);
#endif
- QFileInfoList infoList;
+ QList<std::pair<QString, QFileInfo>> updatedFiles;
+ auto addToUpdatedFiles = [&updatedFiles](QFileInfo &&fileInfo) {
+ fileInfo.stat();
+ updatedFiles.emplace_back(std::pair{translateDriveName(fileInfo), fileInfo});
+ };
+
if (files.isEmpty()) {
- infoList = QDir::drives();
+ // QDir::drives() calls QFSFileEngine::drives() which creates the QFileInfoList on
+ // the stack and return it, so this list is not shared, so no detaching.
+ QFileInfoList infoList = QDir::drives();
+ updatedFiles.reserve(infoList.size());
+ for (auto rit = infoList.rbegin(), rend = infoList.rend(); rit != rend; ++rit)
+ addToUpdatedFiles(std::move(*rit));
} else {
- infoList.reserve(files.count());
- for (const auto &file : files)
- infoList << QFileInfo(file);
- }
- QList<QPair<QString, QFileInfo>> updatedFiles;
- updatedFiles.reserve(infoList.count());
- for (int i = infoList.count() - 1; i >= 0; --i) {
- QFileInfo driveInfo = infoList.at(i);
- driveInfo.stat();
- QString driveName = translateDriveName(driveInfo);
- updatedFiles.append(QPair<QString,QFileInfo>(driveName, driveInfo));
+ updatedFiles.reserve(files.size());
+ for (auto rit = files.crbegin(), rend = files.crend(); rit != rend; ++rit)
+ addToUpdatedFiles(QFileInfo(*rit));
}
emit updates(path, updatedFiles);
return;
@@ -394,15 +414,16 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
base.start();
QFileInfo fileInfo;
bool firstTime = true;
- QList<QPair<QString, QFileInfo>> updatedFiles;
+ QList<std::pair<QString, QFileInfo>> updatedFiles;
QStringList filesToCheck = files;
QStringList allFiles;
if (files.isEmpty()) {
- QDirIterator dirIt(path, QDir::AllEntries | QDir::System | QDir::Hidden);
- while (!abort.loadRelaxed() && dirIt.hasNext()) {
- dirIt.next();
- fileInfo = dirIt.fileInfo();
+ constexpr auto dirFilters = QDir::AllEntries | QDir::System | QDir::Hidden;
+ for (const auto &dirEntry : QDirListing(path, dirFilters)) {
+ if (isInterruptionRequested())
+ break;
+ fileInfo = dirEntry.fileInfo();
fileInfo.stat();
allFiles.append(fileInfo.fileName());
fetch(fileInfo, base, firstTime, updatedFiles, path);
@@ -412,7 +433,7 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
emit newListOfFiles(path, allFiles);
QStringList::const_iterator filesIt = filesToCheck.constBegin();
- while (!abort.loadRelaxed() && filesIt != filesToCheck.constEnd()) {
+ while (!isInterruptionRequested() && filesIt != filesToCheck.constEnd()) {
fileInfo.setFile(path + QDir::separator() + *filesIt);
++filesIt;
fileInfo.stat();
@@ -424,12 +445,12 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
}
void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bool &firstTime,
- QList<QPair<QString, QFileInfo>> &updatedFiles, const QString &path)
+ QList<std::pair<QString, QFileInfo>> &updatedFiles, const QString &path)
{
- updatedFiles.append(QPair<QString, QFileInfo>(fileInfo.fileName(), fileInfo));
+ updatedFiles.emplace_back(std::pair(fileInfo.fileName(), fileInfo));
QElapsedTimer current;
current.start();
- if ((firstTime && updatedFiles.count() > 100) || base.msecsTo(current) > 1000) {
+ if ((firstTime && updatedFiles.size() > 100) || base.msecsTo(current) > 1000) {
emit updates(path, updatedFiles);
updatedFiles.clear();
base = current;
diff --git a/src/gui/itemmodels/qfileinfogatherer_p.h b/src/gui/itemmodels/qfileinfogatherer_p.h
index 374331a588..3d5f59c22e 100644
--- a/src/gui/itemmodels/qfileinfogatherer_p.h
+++ b/src/gui/itemmodels/qfileinfogatherer_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILEINFOGATHERER_H
#define QFILEINFOGATHERER_H
@@ -60,7 +24,6 @@
#include <qfilesystemwatcher.h>
#endif
#include <qabstractfileiconprovider.h>
-#include <qpair.h>
#include <qstack.h>
#include <qdatetime.h>
#include <qdir.h>
@@ -68,6 +31,8 @@
#include <private/qfilesystemengine_p.h>
+#include <utility>
+
QT_REQUIRE_CONFIG(filesystemmodel);
QT_BEGIN_NAMESPACE
@@ -87,7 +52,7 @@ public:
return mFileInfo == fileInfo.mFileInfo
&& displayType == fileInfo.displayType
&& permissions() == fileInfo.permissions()
- && lastModified() == fileInfo.lastModified();
+ && lastModified(QTimeZone::UTC) == fileInfo.lastModified(QTimeZone::UTC);
}
#ifndef QT_NO_FSFILEENGINE
@@ -117,7 +82,7 @@ public:
{
if (ignoreNtfsSymLinks) {
#ifdef Q_OS_WIN
- return !mFileInfo.suffix().compare(QLatin1String("lnk"), Qt::CaseInsensitive);
+ return !mFileInfo.suffix().compare(QLatin1StringView("lnk"), Qt::CaseInsensitive);
#endif
}
return mFileInfo.isSymLink();
@@ -131,8 +96,8 @@ public:
return mFileInfo;
}
- QDateTime lastModified() const {
- return mFileInfo.lastModified();
+ QDateTime lastModified(const QTimeZone &tz) const {
+ return mFileInfo.lastModified(tz);
}
qint64 size() const {
@@ -160,7 +125,7 @@ class Q_GUI_EXPORT QFileInfoGatherer : public QThread
Q_OBJECT
Q_SIGNALS:
- void updates(const QString &directory, const QList<QPair<QString, QFileInfo>> &updates);
+ void updates(const QString &directory, const QList<std::pair<QString, QFileInfo>> &updates);
void newListOfFiles(const QString &directory, const QStringList &listOfFiles) const;
void nameResolved(const QString &fileName, const QString &resolvedName) const;
void directoryLoaded(const QString &path);
@@ -184,6 +149,8 @@ public:
QAbstractFileIconProvider *iconProvider() const;
bool resolveSymlinks() const;
+ void requestAbort();
+
public Q_SLOTS:
void list(const QString &directoryPath);
void fetchExtendedInformation(const QString &path, const QStringList &files);
@@ -195,12 +162,15 @@ private Q_SLOTS:
void driveAdded();
void driveRemoved();
+protected:
+ bool event(QEvent *event) override;
+
private:
void run() override;
// called by run():
void getFileInfos(const QString &path, const QStringList &files);
void fetch(const QFileInfo &info, QElapsedTimer &base, bool &firstTime,
- QList<QPair<QString, QFileInfo>> &updatedFiles, const QString &path);
+ QList<std::pair<QString, QFileInfo>> &updatedFiles, const QString &path);
private:
void createWatcher();
@@ -211,7 +181,6 @@ private:
QStack<QString> path;
QStack<QStringList> files;
// end protected by mutex
- QAtomicInt abort;
#if QT_CONFIG(filesystemwatcher)
QFileSystemWatcher *m_watcher = nullptr;
diff --git a/src/gui/itemmodels/qfilesystemmodel.cpp b/src/gui/itemmodels/qfilesystemmodel.cpp
index 70c274b816..290891322f 100644
--- a/src/gui/itemmodels/qfilesystemmodel.cpp
+++ b/src/gui/itemmodels/qfilesystemmodel.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfilesystemmodel_p.h"
#include "qfilesystemmodel.h"
@@ -59,12 +23,15 @@
QT_BEGIN_NAMESPACE
+using namespace Qt::StringLiterals;
+
/*!
\enum QFileSystemModel::Roles
\value FileIconRole
\value FilePathRole
\value FileNameRole
\value FilePermissions
+ \value FileInfoRole The QFileInfo object for the index
*/
/*!
@@ -142,7 +109,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QIcon QFileSystemModel::fileName(const QModelIndex &index) const
+ \fn QString QFileSystemModel::fileName(const QModelIndex &index) const
Returns the file name for the item stored in the model under the given
\a index.
@@ -177,7 +144,7 @@ QFileInfo QFileSystemModel::fileInfo(const QModelIndex &index) const
\fn void QFileSystemModel::fileRenamed(const QString &path, const QString &oldName, const QString &newName)
This signal is emitted whenever a file with the \a oldName is successfully
- renamed to \a newName. The file is located in in the directory \a path.
+ renamed to \a newName. The file is located in the directory \a path.
*/
/*!
@@ -274,7 +241,7 @@ QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &pare
*/
QModelIndex QFileSystemModel::sibling(int row, int column, const QModelIndex &idx) const
{
- if (row == idx.row() && column < QFileSystemModelPrivate::NumColumns) {
+ if (row == idx.row() && column < columnCount(idx.parent())) {
// cheap sibling operation: just adjust the column:
return createIndex(row, column, idx.internalPointer());
} else {
@@ -314,17 +281,17 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QM
static QString qt_GetLongPathName(const QString &strShortPath)
{
if (strShortPath.isEmpty()
- || strShortPath == QLatin1String(".") || strShortPath == QLatin1String(".."))
+ || strShortPath == "."_L1 || strShortPath == ".."_L1)
return strShortPath;
- if (strShortPath.length() == 2 && strShortPath.endsWith(QLatin1Char(':')))
+ if (strShortPath.length() == 2 && strShortPath.endsWith(u':'))
return strShortPath.toUpper();
const QString absPath = QDir(strShortPath).absolutePath();
- if (absPath.startsWith(QLatin1String("//"))
- || absPath.startsWith(QLatin1String("\\\\"))) // unc
+ if (absPath.startsWith("//"_L1)
+ || absPath.startsWith("\\\\"_L1)) // unc
return QDir::fromNativeSeparators(absPath);
- if (absPath.startsWith(QLatin1Char('/')))
+ if (absPath.startsWith(u'/'))
return QString();
- const QString inputString = QLatin1String("\\\\?\\") + QDir::toNativeSeparators(absPath);
+ const QString inputString = "\\\\?\\"_L1 + QDir::toNativeSeparators(absPath);
QVarLengthArray<TCHAR, MAX_PATH> buffer(MAX_PATH);
DWORD result = ::GetLongPathName((wchar_t*)inputString.utf16(),
buffer.data(),
@@ -354,7 +321,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
{
Q_Q(const QFileSystemModel);
Q_UNUSED(q);
- if (path.isEmpty() || path == myComputer() || path.startsWith(QLatin1Char(':')))
+ if (path.isEmpty() || path == myComputer() || path.startsWith(u':'))
return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root);
// Construct the nodes up to the new root path if they need to be built
@@ -370,30 +337,33 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
absolutePath = QDir(longPath).absolutePath();
// ### TODO can we use bool QAbstractFileEngine::caseSensitive() const?
- QStringList pathElements = absolutePath.split(QLatin1Char('/'), Qt::SkipEmptyParts);
+ QStringList pathElements = absolutePath.split(u'/', Qt::SkipEmptyParts);
if ((pathElements.isEmpty())
#if !defined(Q_OS_WIN)
- && QDir::fromNativeSeparators(longPath) != QLatin1String("/")
+ && QDir::fromNativeSeparators(longPath) != "/"_L1
#endif
)
return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root);
QModelIndex index = QModelIndex(); // start with "My Computer"
QString elementPath;
- QChar separator = QLatin1Char('/');
+ QChar separator = u'/';
QString trailingSeparator;
#if defined(Q_OS_WIN)
- if (absolutePath.startsWith(QLatin1String("//"))) { // UNC path
- QString host = QLatin1String("\\\\") + pathElements.constFirst();
+ if (absolutePath.startsWith("//"_L1)) { // UNC path
+ QString host = "\\\\"_L1 + pathElements.constFirst();
if (absolutePath == QDir::fromNativeSeparators(host))
- absolutePath.append(QLatin1Char('/'));
- if (longPath.endsWith(QLatin1Char('/')) && !absolutePath.endsWith(QLatin1Char('/')))
- absolutePath.append(QLatin1Char('/'));
- if (absolutePath.endsWith(QLatin1Char('/')))
- trailingSeparator = QLatin1String("\\");
+ absolutePath.append(u'/');
+ if (longPath.endsWith(u'/') && !absolutePath.endsWith(u'/'))
+ absolutePath.append(u'/');
+ if (absolutePath.endsWith(u'/'))
+ trailingSeparator = "\\"_L1;
int r = 0;
- QFileSystemModelPrivate::QFileSystemNode *rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root);
- if (!root.children.contains(host.toLower())) {
- if (pathElements.count() == 1 && !absolutePath.endsWith(QLatin1Char('/')))
+ auto rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root);
+ auto it = root.children.constFind(host);
+ if (it != root.children.cend()) {
+ host = it.key(); // Normalize case for lookup in visibleLocation()
+ } else {
+ if (pathElements.count() == 1 && !absolutePath.endsWith(u'/'))
return rootNode;
QFileInfo info(host);
if (!info.exists())
@@ -406,31 +376,31 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
r = translateVisibleLocation(rootNode, r);
index = q->index(r, 0, QModelIndex());
pathElements.pop_front();
- separator = QLatin1Char('\\');
+ separator = u'\\';
elementPath = host;
elementPath.append(separator);
} else {
- if (!pathElements.at(0).contains(QLatin1Char(':'))) {
+ if (!pathElements.at(0).contains(u':')) {
QString rootPath = QDir(longPath).rootPath();
pathElements.prepend(rootPath);
}
- if (pathElements.at(0).endsWith(QLatin1Char('/')))
+ if (pathElements.at(0).endsWith(u'/'))
pathElements[0].chop(1);
}
#else
// add the "/" item, since it is a valid path element on Unix
- if (absolutePath[0] == QLatin1Char('/'))
- pathElements.prepend(QLatin1String("/"));
+ if (absolutePath[0] == u'/')
+ pathElements.prepend("/"_L1);
#endif
QFileSystemModelPrivate::QFileSystemNode *parent = node(index);
- for (int i = 0; i < pathElements.count(); ++i) {
+ for (int i = 0; i < pathElements.size(); ++i) {
QString element = pathElements.at(i);
if (i != 0)
elementPath.append(separator);
elementPath.append(element);
- if (i == pathElements.count() - 1)
+ if (i == pathElements.size() - 1)
elementPath.append(trailingSeparator);
#ifdef Q_OS_WIN
// On Windows, "filename " and "filename" are equivalent and
@@ -440,7 +410,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
// If after stripping the characters there is nothing left then we
// just return the parent directory as it is assumed that the path
// is referring to the parent
- while (element.endsWith(QLatin1Char('.')) || element.endsWith(QLatin1Char(' ')))
+ while (element.endsWith(u'.') || element.endsWith(u' '))
element.chop(1);
// Only filenames that can't possibly exist will be end up being empty
if (element.isEmpty())
@@ -451,7 +421,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
// we couldn't find the path element, we create a new node since we
// _know_ that the path is valid
if (alreadyExisted) {
- if ((parent->children.count() == 0)
+ if ((parent->children.size() == 0)
|| (parent->caseSensitive()
&& parent->children.value(element)->fileName != element)
|| (!parent->caseSensitive()
@@ -469,7 +439,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS
QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this);
node = p->addNode(parent, element,info);
#if QT_CONFIG(filesystemwatcher)
- node->populate(fileInfoGatherer.getInfo(info));
+ node->populate(fileInfoGatherer->getInfo(info));
#endif
} else {
node = parent->children.value(element);
@@ -507,10 +477,10 @@ void QFileSystemModel::timerEvent(QTimerEvent *event)
if (event->timerId() == d->fetchingTimer.timerId()) {
d->fetchingTimer.stop();
#if QT_CONFIG(filesystemwatcher)
- for (int i = 0; i < d->toFetch.count(); ++i) {
+ for (int i = 0; i < d->toFetch.size(); ++i) {
const QFileSystemModelPrivate::QFileSystemNode *node = d->toFetch.at(i).node;
if (!node->hasInformation()) {
- d->fileInfoGatherer.fetchExtendedInformation(d->toFetch.at(i).dir,
+ d->fileInfoGatherer->fetchExtendedInformation(d->toFetch.at(i).dir,
QStringList(d->toFetch.at(i).file));
} else {
// qDebug("yah!, you saved a little gerbil soul");
@@ -560,14 +530,38 @@ QString QFileSystemModel::type(const QModelIndex &index) const
}
/*!
- Returns the date and time when \a index was last modified.
+ Returns the date and time (in local time) when \a index was last modified.
+
+ This is an overloaded function, equivalent to calling:
+ \code
+ lastModified(index, QTimeZone::LocalTime);
+ \endcode
+
+ If \a index is invalid, a default constructed QDateTime is returned.
*/
QDateTime QFileSystemModel::lastModified(const QModelIndex &index) const
{
+ return lastModified(index, QTimeZone::LocalTime);
+}
+
+/*!
+ \since 6.6
+ Returns the date and time, in the time zone \a tz, when
+ \a index was last modified.
+
+ Typical arguments for \a tz are \c QTimeZone::UTC or \c QTimeZone::LocalTime.
+ UTC does not require any conversion from the time returned by the native file
+ system API, therefore getting the time in UTC is potentially faster. LocalTime
+ is typically chosen if the time is shown to the user.
+
+ If \a index is invalid, a default constructed QDateTime is returned.
+ */
+QDateTime QFileSystemModel::lastModified(const QModelIndex &index, const QTimeZone &tz) const
+{
Q_D(const QFileSystemModel);
if (!index.isValid())
return QDateTime();
- return d->node(index)->lastModified();
+ return d->node(index)->lastModified(tz);
}
/*!
@@ -657,7 +651,7 @@ void QFileSystemModel::fetchMore(const QModelIndex &parent)
return;
indexNode->populatedChildren = true;
#if QT_CONFIG(filesystemwatcher)
- d->fileInfoGatherer.list(filePath(parent));
+ d->fileInfoGatherer->list(filePath(parent));
#endif
}
@@ -671,10 +665,10 @@ int QFileSystemModel::rowCount(const QModelIndex &parent) const
return 0;
if (!parent.isValid())
- return d->root.visibleChildren.count();
+ return d->root.visibleChildren.size();
const QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(parent);
- return parentNode->visibleChildren.count();
+ return parentNode->visibleChildren.size();
}
/*!
@@ -700,7 +694,9 @@ QVariant QFileSystemModel::myComputer(int role) const
return QFileSystemModelPrivate::myComputer();
#if QT_CONFIG(filesystemwatcher)
case Qt::DecorationRole:
- return d->fileInfoGatherer.iconProvider()->icon(QAbstractFileIconProvider::Computer);
+ if (auto *provider = d->fileInfoGatherer->iconProvider())
+ return provider->icon(QAbstractFileIconProvider::Computer);
+ break;
#endif
}
return QVariant();
@@ -717,12 +713,15 @@ QVariant QFileSystemModel::data(const QModelIndex &index, int role) const
switch (role) {
case Qt::EditRole:
+ if (index.column() == QFileSystemModelPrivate::NameColumn)
+ return d->name(index);
+ Q_FALLTHROUGH();
case Qt::DisplayRole:
switch (index.column()) {
- case 0: return d->displayName(index);
- case 1: return d->size(index);
- case 2: return d->type(index);
- case 3: return d->time(index);
+ case QFileSystemModelPrivate::NameColumn: return d->displayName(index);
+ case QFileSystemModelPrivate::SizeColumn: return d->size(index);
+ case QFileSystemModelPrivate::TypeColumn: return d->type(index);
+ case QFileSystemModelPrivate::TimeColumn: return d->time(index);
default:
qWarning("data: invalid display value column %d", index.column());
break;
@@ -732,22 +731,23 @@ QVariant QFileSystemModel::data(const QModelIndex &index, int role) const
return filePath(index);
case FileNameRole:
return d->name(index);
+ case FileInfoRole:
+ return QVariant::fromValue(fileInfo(index));
case Qt::DecorationRole:
- if (index.column() == 0) {
+ if (index.column() == QFileSystemModelPrivate::NameColumn) {
QIcon icon = d->icon(index);
#if QT_CONFIG(filesystemwatcher)
if (icon.isNull()) {
- if (d->node(index)->isDir())
- icon = d->fileInfoGatherer.iconProvider()->icon(QAbstractFileIconProvider::Folder);
- else
- icon = d->fileInfoGatherer.iconProvider()->icon(QAbstractFileIconProvider::File);
+ using P = QAbstractFileIconProvider;
+ if (auto *provider = d->fileInfoGatherer->iconProvider())
+ icon = provider->icon(d->node(index)->isDir() ? P::Folder: P::File);
}
#endif // filesystemwatcher
return icon;
}
break;
case Qt::TextAlignmentRole:
- if (index.column() == 1)
+ if (index.column() == QFileSystemModelPrivate::SizeColumn)
return QVariant(Qt::AlignTrailing | Qt::AlignVCenter);
break;
case FilePermissions:
@@ -768,9 +768,9 @@ QString QFileSystemModelPrivate::size(const QModelIndex &index) const
const QFileSystemNode *n = node(index);
if (n->isDir()) {
#ifdef Q_OS_MAC
- return QLatin1String("--");
+ return "--"_L1;
#else
- return QLatin1String("");
+ return ""_L1;
#endif
// Windows - ""
// OS X - "--"
@@ -793,7 +793,7 @@ QString QFileSystemModelPrivate::time(const QModelIndex &index) const
if (!index.isValid())
return QString();
#if QT_CONFIG(datestring)
- return QLocale::system().toString(node(index)->lastModified(), QLocale::ShortFormat);
+ return QLocale::system().toString(node(index)->lastModified(QTimeZone::LocalTime), QLocale::ShortFormat);
#else
Q_UNUSED(index);
return QString();
@@ -820,7 +820,7 @@ QString QFileSystemModelPrivate::name(const QModelIndex &index) const
QFileSystemNode *dirNode = node(index);
if (
#if QT_CONFIG(filesystemwatcher)
- fileInfoGatherer.resolveSymlinks() &&
+ fileInfoGatherer->resolveSymlinks() &&
#endif
!resolvedSymLinks.isEmpty() && dirNode->isSymLink(/* ignoreNtfsSymLinks = */ true)) {
QString fullPath = QDir::fromNativeSeparators(filePath(index));
@@ -890,7 +890,7 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in
*After re-naming something we don't want the selection to change*
- can't remove rows and later insert
- can't quickly remove and insert
- - index pointer can't change because treeview doesn't use persistant index's
+ - index pointer can't change because treeview doesn't use persistent index's
- if this get any more complicated think of changing it to just
use layoutChanged
@@ -901,14 +901,14 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in
int visibleLocation = parentNode->visibleLocation(parentNode->children.value(indexNode->fileName)->fileName);
parentNode->visibleChildren.removeAt(visibleLocation);
- QScopedPointer<QFileSystemModelPrivate::QFileSystemNode> nodeToRename(parentNode->children.take(oldName));
+ std::unique_ptr<QFileSystemModelPrivate::QFileSystemNode> nodeToRename(parentNode->children.take(oldName));
nodeToRename->fileName = newName;
nodeToRename->parent = parentNode;
#if QT_CONFIG(filesystemwatcher)
- nodeToRename->populate(d->fileInfoGatherer.getInfo(QFileInfo(parentPath, newName)));
+ nodeToRename->populate(d->fileInfoGatherer->getInfo(QFileInfo(parentPath, newName)));
#endif
nodeToRename->isVisible = true;
- parentNode->children[newName] = nodeToRename.take();
+ parentNode->children[newName] = nodeToRename.release();
parentNode->visibleChildren.insert(visibleLocation, newName);
d->delayedSort();
@@ -941,23 +941,27 @@ QVariant QFileSystemModel::headerData(int section, Qt::Orientation orientation,
QString returnValue;
switch (section) {
- case 0: returnValue = tr("Name");
- break;
- case 1: returnValue = tr("Size");
- break;
- case 2: returnValue =
+ case QFileSystemModelPrivate::NameColumn:
+ returnValue = tr("Name");
+ break;
+ case QFileSystemModelPrivate::SizeColumn:
+ returnValue = tr("Size");
+ break;
+ case QFileSystemModelPrivate::TypeColumn:
+ returnValue =
#ifdef Q_OS_MAC
- tr("Kind", "Match OS X Finder");
+ tr("Kind", "Match OS X Finder");
#else
- tr("Type", "All other platforms");
+ tr("Type", "All other platforms");
#endif
- break;
+ break;
// Windows - Type
// OS X - Kind
// Konqueror - File Type
// Nautilus - Type
- case 3: returnValue = tr("Date Modified");
- break;
+ case QFileSystemModelPrivate::TimeColumn:
+ returnValue = tr("Date Modified");
+ break;
default: return QVariant();
}
return returnValue;
@@ -981,14 +985,15 @@ Qt::ItemFlags QFileSystemModel::flags(const QModelIndex &index) const
}
flags |= Qt::ItemIsDragEnabled;
+
+ if (!indexNode->isDir())
+ flags |= Qt::ItemNeverHasChildren;
if (d->readOnly)
return flags;
if ((index.column() == 0) && indexNode->permissions() & QFile::WriteUser) {
flags |= Qt::ItemIsEditable;
if (indexNode->isDir())
flags |= Qt::ItemIsDropEnabled;
- else
- flags |= Qt::ItemNeverHasChildren;
}
return flags;
}
@@ -996,7 +1001,7 @@ Qt::ItemFlags QFileSystemModel::flags(const QModelIndex &index) const
/*!
\internal
*/
-void QFileSystemModelPrivate::_q_performDelayedSort()
+void QFileSystemModelPrivate::performDelayedSort()
{
Q_Q(QFileSystemModel);
q->sort(sortColumn, sortOrder);
@@ -1020,7 +1025,7 @@ public:
const QFileSystemModelPrivate::QFileSystemNode *r) const
{
switch (sortColumn) {
- case 0: {
+ case QFileSystemModelPrivate::NameColumn: {
#ifndef Q_OS_MAC
// place directories before files
bool left = l->isDir();
@@ -1030,7 +1035,7 @@ public:
#endif
return naturalCompare.compare(l->fileName, r->fileName) < 0;
}
- case 1:
+ case QFileSystemModelPrivate::SizeColumn:
{
// Directories go first
bool left = l->isDir();
@@ -1044,7 +1049,7 @@ public:
return sizeDifference < 0;
}
- case 2:
+ case QFileSystemModelPrivate::TypeColumn:
{
int compare = naturalCompare.compare(l->type(), r->type());
if (compare == 0)
@@ -1052,12 +1057,14 @@ public:
return compare < 0;
}
- case 3:
+ case QFileSystemModelPrivate::TimeColumn:
{
- if (l->lastModified() == r->lastModified())
+ const QDateTime left = l->lastModified(QTimeZone::UTC);
+ const QDateTime right = r->lastModified(QTimeZone::UTC);
+ if (left == right)
return naturalCompare.compare(l->fileName, r->fileName) < 0;
- return l->lastModified() < r->lastModified();
+ return left < right;
}
}
Q_ASSERT(false);
@@ -1085,7 +1092,7 @@ void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent
{
Q_Q(QFileSystemModel);
QFileSystemModelPrivate::QFileSystemNode *indexNode = node(parent);
- if (indexNode->children.count() == 0)
+ if (indexNode->children.size() == 0)
return;
QList<QFileSystemModelPrivate::QFileSystemNode *> values;
@@ -1103,11 +1110,10 @@ void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent
indexNode->visibleChildren.clear();
//No more dirty item we reset our internal dirty index
indexNode->dirtyChildrenIndex = -1;
- 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;
+ indexNode->visibleChildren.reserve(values.size());
+ for (QFileSystemNode *node : std::as_const(values)) {
+ indexNode->visibleChildren.append(node->fileName);
+ node->isVisible = true;
}
if (!disableRecursiveSort) {
@@ -1133,10 +1139,8 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order)
emit layoutAboutToBeChanged();
QModelIndexList oldList = persistentIndexList();
QList<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);
+ oldNodes.reserve(oldList.size());
+ for (const QModelIndex &oldNode : oldList) {
QPair<QFileSystemModelPrivate::QFileSystemNode*, int> pair(d->node(oldNode), oldNode.column());
oldNodes.append(pair);
}
@@ -1150,12 +1154,10 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order)
d->sortOrder = order;
QModelIndexList newList;
- 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));
- }
+ newList.reserve(oldNodes.size());
+ for (const auto &[node, col]: std::as_const(oldNodes))
+ newList.append(d->index(node, col));
+
changePersistentIndexList(oldList, newList);
emit layoutChanged();
}
@@ -1166,7 +1168,7 @@ void QFileSystemModel::sort(int column, Qt::SortOrder order)
*/
QStringList QFileSystemModel::mimeTypes() const
{
- return QStringList(QLatin1String("text/uri-list"));
+ return QStringList("text/uri-list"_L1);
}
/*!
@@ -1182,7 +1184,7 @@ QMimeData *QFileSystemModel::mimeData(const QModelIndexList &indexes) const
QList<QUrl> urls;
QList<QModelIndex>::const_iterator it = indexes.begin();
for (; it != indexes.end(); ++it)
- if ((*it).column() == 0)
+ if ((*it).column() == QFileSystemModelPrivate::NameColumn)
urls << QUrl::fromLocalFile(filePath(*it));
QMimeData *data = new QMimeData();
data->setUrls(urls);
@@ -1256,6 +1258,7 @@ QHash<int, QByteArray> QFileSystemModel::roleNames() const
ret.insert(QFileSystemModel::FilePathRole, QByteArrayLiteral("filePath"));
ret.insert(QFileSystemModel::FileNameRole, QByteArrayLiteral("fileName"));
ret.insert(QFileSystemModel::FilePermissions, QByteArrayLiteral("filePermissions"));
+ ret.insert(QFileSystemModel::FileInfoRole, QByteArrayLiteral("fileInfo"));
return ret;
}
@@ -1328,7 +1331,7 @@ void QFileSystemModel::setOptions(Options options)
#if QT_CONFIG(filesystemwatcher)
Q_D(QFileSystemModel);
if (changed.testFlag(DontWatchForChanges))
- d->fileInfoGatherer.setWatching(!options.testFlag(DontWatchForChanges));
+ d->fileInfoGatherer->setWatching(!options.testFlag(DontWatchForChanges));
#endif
if (changed.testFlag(DontUseCustomDirectoryIcons)) {
@@ -1349,7 +1352,7 @@ QFileSystemModel::Options QFileSystemModel::options() const
result.setFlag(DontResolveSymlinks, !resolveSymlinks());
#if QT_CONFIG(filesystemwatcher)
Q_D(const QFileSystemModel);
- result.setFlag(DontWatchForChanges, !d->fileInfoGatherer.isWatching());
+ result.setFlag(DontWatchForChanges, !d->fileInfoGatherer->isWatching());
#else
result.setFlag(DontWatchForChanges);
#endif
@@ -1371,7 +1374,7 @@ QString QFileSystemModel::filePath(const QModelIndex &index) const
QFileSystemModelPrivate::QFileSystemNode *dirNode = d->node(index);
if (dirNode->isSymLink()
#if QT_CONFIG(filesystemwatcher)
- && d->fileInfoGatherer.resolveSymlinks()
+ && d->fileInfoGatherer->resolveSymlinks()
#endif
&& d->resolvedSymLinks.contains(fullPath)
&& dirNode->isDir()) {
@@ -1407,11 +1410,11 @@ QString QFileSystemModelPrivate::filePath(const QModelIndex &index) const
}
QString fullPath = QDir::fromNativeSeparators(path.join(QDir::separator()));
#if !defined(Q_OS_WIN)
- if ((fullPath.length() > 2) && fullPath[0] == QLatin1Char('/') && fullPath[1] == QLatin1Char('/'))
+ if ((fullPath.size() > 2) && fullPath[0] == u'/' && fullPath[1] == u'/')
fullPath = fullPath.mid(1);
#else
- if (fullPath.length() == 2 && fullPath.endsWith(QLatin1Char(':')))
- fullPath.append(QLatin1Char('/'));
+ if (fullPath.length() == 2 && fullPath.endsWith(u':'))
+ fullPath.append(u'/');
#endif
return fullPath;
}
@@ -1433,7 +1436,7 @@ QModelIndex QFileSystemModel::mkdir(const QModelIndex &parent, const QString &na
Q_ASSERT(parentNode->children.contains(name));
QFileSystemModelPrivate::QFileSystemNode *node = parentNode->children[name];
#if QT_CONFIG(filesystemwatcher)
- node->populate(d->fileInfoGatherer.getInfo(QFileInfo(dir.absolutePath() + QDir::separator() + name)));
+ node->populate(d->fileInfoGatherer->getInfo(QFileInfo(dir.absolutePath() + QDir::separator() + name)));
#endif
d->addVisibleFiles(parentNode, QStringList(name));
return d->index(node);
@@ -1498,10 +1501,10 @@ QModelIndex QFileSystemModel::setRootPath(const QString &newPath)
return d->index(rootPath());
//We remove the watcher on the previous path
- if (!rootPath().isEmpty() && rootPath() != QLatin1String(".")) {
+ if (!rootPath().isEmpty() && rootPath() != "."_L1) {
//This remove the watcher for the old rootPath
#if QT_CONFIG(filesystemwatcher)
- d->fileInfoGatherer.removePath(rootPath());
+ d->fileInfoGatherer->removePath(rootPath());
#endif
//This line "marks" the node as dirty, so the next fetchMore
//call on the path will ask the gatherer to install a watcher again
@@ -1514,7 +1517,7 @@ QModelIndex QFileSystemModel::setRootPath(const QString &newPath)
QModelIndex newRootIndex;
if (showDrives) {
// otherwise dir will become '.'
- d->rootDir.setPath(QLatin1String(""));
+ d->rootDir.setPath(""_L1);
} else {
newRootIndex = d->index(d->rootDir.path());
}
@@ -1557,7 +1560,7 @@ void QFileSystemModel::setIconProvider(QAbstractFileIconProvider *provider)
{
Q_D(QFileSystemModel);
#if QT_CONFIG(filesystemwatcher)
- d->fileInfoGatherer.setIconProvider(provider);
+ d->fileInfoGatherer->setIconProvider(provider);
#endif
d->root.updateIcon(provider, QString());
}
@@ -1569,9 +1572,9 @@ QAbstractFileIconProvider *QFileSystemModel::iconProvider() const
{
#if QT_CONFIG(filesystemwatcher)
Q_D(const QFileSystemModel);
- return d->fileInfoGatherer.iconProvider();
+ return d->fileInfoGatherer->iconProvider();
#else
- return 0;
+ return nullptr;
#endif
}
@@ -1588,9 +1591,11 @@ void QFileSystemModel::setFilter(QDir::Filters filters)
Q_D(QFileSystemModel);
if (d->filters == filters)
return;
+ const bool changingCaseSensitivity =
+ filters.testFlag(QDir::CaseSensitive) != d->filters.testFlag(QDir::CaseSensitive);
d->filters = filters;
- // CaseSensitivity might have changed
- setNameFilters(nameFilters());
+ if (changingCaseSensitivity)
+ d->rebuildNameFilterRegexps();
d->forceSort = true;
d->delayedSort();
}
@@ -1623,7 +1628,7 @@ void QFileSystemModel::setResolveSymlinks(bool enable)
{
#if QT_CONFIG(filesystemwatcher)
Q_D(QFileSystemModel);
- d->fileInfoGatherer.setResolveSymlinks(enable);
+ d->fileInfoGatherer->setResolveSymlinks(enable);
#else
Q_UNUSED(enable);
#endif
@@ -1633,7 +1638,7 @@ bool QFileSystemModel::resolveSymlinks() const
{
#if QT_CONFIG(filesystemwatcher)
Q_D(const QFileSystemModel);
- return d->fileInfoGatherer.resolveSymlinks();
+ return d->fileInfoGatherer->resolveSymlinks();
#else
return false;
#endif
@@ -1687,7 +1692,6 @@ bool QFileSystemModel::nameFilterDisables() const
*/
void QFileSystemModel::setNameFilters(const QStringList &filters)
{
- // Prep the regexp's ahead of time
#if QT_CONFIG(regularexpression)
Q_D(QFileSystemModel);
@@ -1710,6 +1714,7 @@ void QFileSystemModel::setNameFilters(const QStringList &filters)
}
d->nameFilters = filters;
+ d->rebuildNameFilterRegexps();
d->forceSort = true;
d->delayedSort();
#else
@@ -1738,7 +1743,7 @@ bool QFileSystemModel::event(QEvent *event)
#if QT_CONFIG(filesystemwatcher)
Q_D(QFileSystemModel);
if (event->type() == QEvent::LanguageChange) {
- d->root.retranslateStrings(d->fileInfoGatherer.iconProvider(), QString());
+ d->root.retranslateStrings(d->fileInfoGatherer->iconProvider(), QString());
return true;
}
#endif
@@ -1752,7 +1757,7 @@ bool QFileSystemModel::rmdir(const QModelIndex &aindex)
#if QT_CONFIG(filesystemwatcher)
if (success) {
QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
- d->fileInfoGatherer.removePath(path);
+ d->fileInfoGatherer->removePath(path);
}
#endif
return success;
@@ -1764,10 +1769,10 @@ bool QFileSystemModel::rmdir(const QModelIndex &aindex)
Performed quick listing and see if any files have been added or removed,
then fetch more information on visible files.
*/
-void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, const QStringList &files)
+void QFileSystemModelPrivate::directoryChanged(const QString &directory, const QStringList &files)
{
QFileSystemModelPrivate::QFileSystemNode *parentNode = node(directory, false);
- if (parentNode->children.count() == 0)
+ if (parentNode->children.size() == 0)
return;
QStringList toRemove;
QStringList newFiles = files;
@@ -1777,7 +1782,7 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons
if ((iterator == newFiles.end()) || (i.value()->fileName < *iterator))
toRemove.append(i.value()->fileName);
}
- for (int i = 0 ; i < toRemove.count() ; ++i )
+ for (int i = 0 ; i < toRemove.size() ; ++i )
removeNode(parentNode, toRemove[i]);
}
@@ -1869,11 +1874,11 @@ void QFileSystemModelPrivate::addVisibleFiles(QFileSystemNode *parentNode, const
QModelIndex parent = index(parentNode);
bool indexHidden = isHiddenByFilter(parentNode, parent);
if (!indexHidden) {
- q->beginInsertRows(parent, parentNode->visibleChildren.count() , parentNode->visibleChildren.count() + newFiles.count() - 1);
+ q->beginInsertRows(parent, parentNode->visibleChildren.size() , parentNode->visibleChildren.size() + newFiles.size() - 1);
}
if (parentNode->dirtyChildrenIndex == -1)
- parentNode->dirtyChildrenIndex = parentNode->visibleChildren.count();
+ parentNode->dirtyChildrenIndex = parentNode->visibleChildren.size();
for (const auto &newFile : newFiles) {
parentNode->visibleChildren.append(newFile);
@@ -1912,8 +1917,8 @@ 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::fileSystemChanged(const QString &path,
+ const QList<std::pair<QString, QFileInfo>> &updates)
{
#if QT_CONFIG(filesystemwatcher)
Q_Q(QFileSystemModel);
@@ -1924,7 +1929,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path,
for (const auto &update : updates) {
QString fileName = update.first;
Q_ASSERT(!fileName.isEmpty());
- QExtendedInformation info = fileInfoGatherer.getInfo(update.second);
+ QExtendedInformation info = fileInfoGatherer->getInfo(update.second);
bool previouslyHere = parentNode->children.contains(fileName);
if (!previouslyHere) {
addNode(parentNode, fileName, info.fileInfo());
@@ -1969,7 +1974,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path,
std::sort(rowsToUpdate.begin(), rowsToUpdate.end());
QString min;
QString max;
- for (const QString &value : qAsConst(rowsToUpdate)) {
+ for (const QString &value : std::as_const(rowsToUpdate)) {
//##TODO is there a way to bundle signals with QString as the content of the list?
/*if (min.isEmpty()) {
min = value;
@@ -1987,23 +1992,30 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path,
int visibleMin = parentNode->visibleLocation(min);
int visibleMax = parentNode->visibleLocation(max);
if (visibleMin >= 0
- && visibleMin < parentNode->visibleChildren.count()
+ && visibleMin < parentNode->visibleChildren.size()
&& parentNode->visibleChildren.at(visibleMin) == min
&& visibleMax >= 0) {
- QModelIndex bottom = q->index(translateVisibleLocation(parentNode, visibleMin), 0, parentIndex);
- QModelIndex top = q->index(translateVisibleLocation(parentNode, visibleMax), 3, parentIndex);
- emit q->dataChanged(bottom, top);
+ // don't use NumColumns here, a subclass might override columnCount
+ const int lastColumn = q->columnCount(parentIndex) - 1;
+ const QModelIndex top = q->index(translateVisibleLocation(parentNode, visibleMin),
+ QFileSystemModelPrivate::NameColumn, parentIndex);
+ const QModelIndex bottom = q->index(translateVisibleLocation(parentNode, visibleMax),
+ lastColumn, parentIndex);
+ // We document that emitting dataChanged with indexes that don't have the
+ // same parent is undefined behavior.
+ Q_ASSERT(bottom.parent() == top.parent());
+ emit q->dataChanged(top, bottom);
}
/*min = QString();
max = QString();*/
}
- if (newFiles.count() > 0) {
+ if (newFiles.size() > 0) {
addVisibleFiles(parentNode, newFiles);
}
- if (newFiles.count() > 0 || (sortColumn != 0 && rowsToUpdate.count() > 0)) {
+ if (newFiles.size() > 0 || (sortColumn != 0 && rowsToUpdate.size() > 0)) {
forceSort = true;
delayedSort();
}
@@ -2016,7 +2028,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path,
/*!
\internal
*/
-void QFileSystemModelPrivate::_q_resolvedName(const QString &fileName, const QString &resolvedName)
+void QFileSystemModelPrivate::resolvedName(const QString &fileName, const QString &resolvedName)
{
resolvedSymLinks[fileName] = resolvedName;
}
@@ -2042,25 +2054,48 @@ QStringList QFileSystemModelPrivate::unwatchPathsAt(const QModelIndex &index)
if (pathSize == watchedPath.size()) {
return path.compare(watchedPath, caseSensitivity) == 0;
} else if (watchedPath.size() > pathSize) {
- return watchedPath.at(pathSize) == QLatin1Char('/')
+ return watchedPath.at(pathSize) == u'/'
&& watchedPath.startsWith(path, caseSensitivity);
}
return false;
};
- const QStringList &watchedFiles = fileInfoGatherer.watchedFiles();
+ const QStringList &watchedFiles = fileInfoGatherer->watchedFiles();
std::copy_if(watchedFiles.cbegin(), watchedFiles.cend(),
std::back_inserter(result), filter);
- const QStringList &watchedDirectories = fileInfoGatherer.watchedDirectories();
+ const QStringList &watchedDirectories = fileInfoGatherer->watchedDirectories();
std::copy_if(watchedDirectories.cbegin(), watchedDirectories.cend(),
std::back_inserter(result), filter);
- fileInfoGatherer.unwatchPaths(result);
+ fileInfoGatherer->unwatchPaths(result);
return result;
}
#endif // filesystemwatcher && Q_OS_WIN
+QFileSystemModelPrivate::QFileSystemModelPrivate()
+#if QT_CONFIG(filesystemwatcher)
+ : fileInfoGatherer(new QFileInfoGatherer)
+#endif // filesystemwatcher
+{
+}
+
+QFileSystemModelPrivate::~QFileSystemModelPrivate()
+{
+#if QT_CONFIG(filesystemwatcher)
+ fileInfoGatherer->requestAbort();
+ if (!fileInfoGatherer->wait(1000)) {
+ // If the thread hangs, perhaps because the network was disconnected
+ // while the gatherer was stat'ing a remote file, then don't block
+ // shutting down the model (which might block a file dialog and the
+ // main thread). Schedule the gatherer for later deletion; it's
+ // destructor will wait for the thread to finish.
+ auto *rawGatherer = fileInfoGatherer.release();
+ rawGatherer->deleteLater();
+ }
+#endif // filesystemwatcher
+}
+
/*!
\internal
*/
@@ -2070,18 +2105,20 @@ void QFileSystemModelPrivate::init()
delayedSortTimer.setSingleShot(true);
- qRegisterMetaType<QList<QPair<QString, QFileInfo>>>();
+ qRegisterMetaType<QList<std::pair<QString, QFileInfo>>>();
#if QT_CONFIG(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(nameResolved(QString,QString)),
- q, SLOT(_q_resolvedName(QString,QString)));
- q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)),
- q, SIGNAL(directoryLoaded(QString)));
+ QObjectPrivate::connect(fileInfoGatherer.get(), &QFileInfoGatherer::newListOfFiles,
+ this, &QFileSystemModelPrivate::directoryChanged);
+ QObjectPrivate::connect(fileInfoGatherer.get(), &QFileInfoGatherer::updates,
+ this, &QFileSystemModelPrivate::fileSystemChanged);
+ QObjectPrivate::connect(fileInfoGatherer.get(), &QFileInfoGatherer::nameResolved,
+ this, &QFileSystemModelPrivate::resolvedName);
+ q->connect(fileInfoGatherer.get(), &QFileInfoGatherer::directoryLoaded,
+ q, &QFileSystemModel::directoryLoaded);
#endif // filesystemwatcher
- q->connect(&delayedSortTimer, SIGNAL(timeout()), q, SLOT(_q_performDelayedSort()), Qt::QueuedConnection);
+ QObjectPrivate::connect(&delayedSortTimer, &QTimer::timeout,
+ this, &QFileSystemModelPrivate::performDelayedSort,
+ Qt::QueuedConnection);
}
/*!
@@ -2094,8 +2131,14 @@ void QFileSystemModelPrivate::init()
*/
bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) const
{
+ // When the model is set to only show files, then a node representing a dir
+ // should be hidden regardless of bypassFilters.
+ // QTBUG-74471
+ const bool hideDirs = (filters & (QDir::Dirs | QDir::AllDirs)) == 0;
+ const bool shouldHideDirNode = hideDirs && node->isDir();
+
// always accept drives
- if (node->parent == &root || bypassFilters.contains(node))
+ if (node->parent == &root || (!shouldHideDirNode && bypassFilters.contains(node)))
return true;
// If we don't know anything yet don't accept it
@@ -2104,7 +2147,6 @@ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) co
const bool filterPermissions = ((filters & QDir::PermissionMask)
&& (filters & QDir::PermissionMask) != QDir::PermissionMask);
- const bool hideDirs = !(filters & (QDir::Dirs | QDir::AllDirs));
const bool hideFiles = !(filters & QDir::Files);
const bool hideReadable = !(!filterPermissions || (filters & QDir::Readable));
const bool hideWritable = !(!filterPermissions || (filters & QDir::Writable));
@@ -2116,8 +2158,8 @@ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) co
const bool hideDotDot = (filters & QDir::NoDotDot);
// Note that we match the behavior of entryList and not QFileInfo on this.
- bool isDot = (node->fileName == QLatin1String("."));
- bool isDotDot = (node->fileName == QLatin1String(".."));
+ bool isDot = (node->fileName == "."_L1);
+ bool isDotDot = (node->fileName == ".."_L1);
if ( (hideHidden && !(isDot || isDotDot) && node->isHidden())
|| (hideSystem && node->isSystem())
|| (hideDirs && node->isDir())
@@ -2146,15 +2188,13 @@ bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const
// Check the name regularexpression filters
if (!(node->isDir() && (filters & QDir::AllDirs))) {
- auto cs = (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
-
- for (const auto &nameFilter : nameFilters) {
- auto rx = QRegularExpression::fromWildcard(nameFilter, cs);
- QRegularExpressionMatch match = rx.match(node->fileName);
- if (match.hasMatch())
- return true;
- }
- return false;
+ const auto matchesNodeFileName = [node](const QRegularExpression &re)
+ {
+ return node->fileName.contains(re);
+ };
+ return std::any_of(nameFiltersRegexps.begin(),
+ nameFiltersRegexps.end(),
+ matchesNodeFileName);
}
#else
Q_UNUSED(node);
@@ -2162,6 +2202,23 @@ bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const
return true;
}
+#if QT_CONFIG(regularexpression)
+void QFileSystemModelPrivate::rebuildNameFilterRegexps()
+{
+ nameFiltersRegexps.clear();
+ nameFiltersRegexps.reserve(nameFilters.size());
+ const auto cs = (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ const auto convertWildcardToRegexp = [cs](const QString &nameFilter)
+ {
+ return QRegularExpression::fromWildcard(nameFilter, cs);
+ };
+ std::transform(nameFilters.constBegin(),
+ nameFilters.constEnd(),
+ std::back_inserter(nameFiltersRegexps),
+ convertWildcardToRegexp);
+}
+#endif
+
QT_END_NAMESPACE
#include "moc_qfilesystemmodel.cpp"
diff --git a/src/gui/itemmodels/qfilesystemmodel.h b/src/gui/itemmodels/qfilesystemmodel.h
index a79c4c14df..1fd1041f15 100644
--- a/src/gui/itemmodels/qfilesystemmodel.h
+++ b/src/gui/itemmodels/qfilesystemmodel.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMMODEL_H
#define QFILESYSTEMMODEL_H
@@ -45,7 +9,6 @@
#include <QtCore/qpair.h>
#include <QtCore/qdir.h>
#include <QtGui/qicon.h>
-#include <QtCore/qdiriterator.h>
QT_REQUIRE_CONFIG(filesystemmodel);
@@ -69,11 +32,13 @@ Q_SIGNALS:
void directoryLoaded(const QString &path);
public:
+ // ### Qt 7: renumber these values to be before Qt::UserRole comment.
enum Roles {
FileIconRole = Qt::DecorationRole,
+ FileInfoRole = Qt::UserRole - 1,
FilePathRole = Qt::UserRole + 1,
FileNameRole = Qt::UserRole + 2,
- FilePermissions = Qt::UserRole + 3
+ FilePermissions = Qt::UserRole + 3,
};
enum Option
@@ -149,7 +114,9 @@ public:
bool isDir(const QModelIndex &index) const;
qint64 size(const QModelIndex &index) const;
QString type(const QModelIndex &index) const;
+
QDateTime lastModified(const QModelIndex &index) const;
+ QDateTime lastModified(const QModelIndex &index, const QTimeZone &tz) const;
QModelIndex mkdir(const QModelIndex &parent, const QString &name);
bool rmdir(const QModelIndex &index);
@@ -168,13 +135,6 @@ private:
Q_DECLARE_PRIVATE(QFileSystemModel)
Q_DISABLE_COPY(QFileSystemModel)
- Q_PRIVATE_SLOT(d_func(), void _q_directoryChanged(const QString &directory, const QStringList &list))
- Q_PRIVATE_SLOT(d_func(), void _q_performDelayedSort())
- Q_PRIVATE_SLOT(d_func(),
- void _q_fileSystemChanged(const QString &path,
- const QList<QPair<QString, QFileInfo>> &))
- Q_PRIVATE_SLOT(d_func(), void _q_resolvedName(const QString &fileName, const QString &resolvedName))
-
friend class QFileDialogPrivate;
};
diff --git a/src/gui/itemmodels/qfilesystemmodel_p.h b/src/gui/itemmodels/qfilesystemmodel_p.h
index 4acd6a92df..e01b0d56e6 100644
--- a/src/gui/itemmodels/qfilesystemmodel_p.h
+++ b/src/gui/itemmodels/qfilesystemmodel_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILESYSTEMMODEL_P_H
#define QFILESYSTEMMODEL_P_H
@@ -64,6 +28,8 @@
#include <qtimer.h>
#include <qhash.h>
+#include <vector>
+
QT_REQUIRE_CONFIG(filesystemmodel);
QT_BEGIN_NAMESPACE
@@ -84,7 +50,10 @@ public:
Q_DECLARE_TYPEINFO(QFileSystemModelNodePathKey, Q_RELOCATABLE_TYPE);
-inline size_t qHash(const QFileSystemModelNodePathKey &key) { return qHash(key.toCaseFolded()); }
+inline size_t qHash(const QFileSystemModelNodePathKey &key, size_t seed = 0)
+{
+ return qHash(key.toCaseFolded(), seed);
+}
#else // Q_OS_WIN
typedef QString QFileSystemModelNodePathKey;
#endif
@@ -94,7 +63,13 @@ class Q_GUI_EXPORT QFileSystemModelPrivate : public QAbstractItemModelPrivate
Q_DECLARE_PUBLIC(QFileSystemModel)
public:
- enum { NumColumns = 4 };
+ enum {
+ NameColumn,
+ SizeColumn,
+ TypeColumn,
+ TimeColumn,
+ NumColumns = 4
+ };
class QFileSystemNode
{
@@ -114,8 +89,8 @@ public:
#endif
inline qint64 size() const { if (info && !info->isDir()) return info->size(); return 0; }
- inline QString type() const { if (info) return info->displayType; return QLatin1String(""); }
- inline QDateTime lastModified() const { if (info) return info->lastModified(); return QDateTime(); }
+ inline QString type() const { if (info) return info->displayType; return QLatin1StringView(""); }
+ inline QDateTime lastModified(const QTimeZone &tz) const { return info ? info->lastModified(tz) : QDateTime(); }
inline QFile::Permissions permissions() const { if (info) return info->permissions(); return { }; }
inline bool isReadable() const { return ((permissions() & QFile::ReadUser) != 0); }
inline bool isWritable() const { return ((permissions() & QFile::WriteUser) != 0); }
@@ -123,7 +98,7 @@ public:
inline bool isDir() const {
if (info)
return info->isDir();
- if (children.count() > 0)
+ if (children.size() > 0)
return true;
return false;
}
@@ -175,30 +150,37 @@ public:
return visibleChildren.indexOf(childName);
}
void updateIcon(QAbstractFileIconProvider *iconProvider, const QString &path) {
+ if (!iconProvider)
+ return;
+
if (info)
info->icon = iconProvider->icon(QFileInfo(path));
- for (QFileSystemNode *child : qAsConst(children)) {
+
+ for (QFileSystemNode *child : std::as_const(children)) {
//On windows the root (My computer) has no path so we don't want to add a / for nothing (e.g. /C:/)
if (!path.isEmpty()) {
- if (path.endsWith(QLatin1Char('/')))
+ if (path.endsWith(u'/'))
child->updateIcon(iconProvider, path + child->fileName);
else
- child->updateIcon(iconProvider, path + QLatin1Char('/') + child->fileName);
+ child->updateIcon(iconProvider, path + u'/' + child->fileName);
} else
child->updateIcon(iconProvider, child->fileName);
}
}
void retranslateStrings(QAbstractFileIconProvider *iconProvider, const QString &path) {
+ if (!iconProvider)
+ return;
+
if (info)
info->displayType = iconProvider->type(QFileInfo(path));
- for (QFileSystemNode *child : qAsConst(children)) {
+ for (QFileSystemNode *child : std::as_const(children)) {
//On windows the root (My computer) has no path so we don't want to add a / for nothing (e.g. /C:/)
if (!path.isEmpty()) {
- if (path.endsWith(QLatin1Char('/')))
+ if (path.endsWith(u'/'))
child->retranslateStrings(iconProvider, path + child->fileName);
else
- child->retranslateStrings(iconProvider, path + QLatin1Char('/') + child->fileName);
+ child->retranslateStrings(iconProvider, path + u'/' + child->fileName);
} else
child->retranslateStrings(iconProvider, child->fileName);
}
@@ -213,7 +195,8 @@ public:
bool isVisible = false;
};
- QFileSystemModelPrivate() = default;
+ QFileSystemModelPrivate();
+ ~QFileSystemModelPrivate();
void init();
/*
\internal
@@ -239,7 +222,7 @@ public:
inline int translateVisibleLocation(QFileSystemNode *parent, int row) const {
if (sortOrder != Qt::AscendingOrder) {
if (parent->dirtyChildrenIndex == -1)
- return parent->visibleChildren.count() - row - 1;
+ return parent->visibleChildren.size() - row - 1;
if (row < parent->dirtyChildrenIndex)
return parent->dirtyChildrenIndex - row - 1;
@@ -274,23 +257,25 @@ public:
QString type(const QModelIndex &index) const;
QString time(const QModelIndex &index) const;
- void _q_directoryChanged(const QString &directory, const QStringList &list);
- void _q_performDelayedSort();
- void _q_fileSystemChanged(const QString &path, const QList<QPair<QString, QFileInfo>> &);
- void _q_resolvedName(const QString &fileName, const QString &resolvedName);
+ void directoryChanged(const QString &directory, const QStringList &list);
+ void performDelayedSort();
+ void fileSystemChanged(const QString &path, const QList<std::pair<QString, QFileInfo>> &);
+ void resolvedName(const QString &fileName, const QString &resolvedName);
QDir rootDir;
#if QT_CONFIG(filesystemwatcher)
# ifdef Q_OS_WIN
QStringList unwatchPathsAt(const QModelIndex &);
- void watchPaths(const QStringList &paths) { fileInfoGatherer.watchPaths(paths); }
+ void watchPaths(const QStringList &paths) { fileInfoGatherer->watchPaths(paths); }
# endif // Q_OS_WIN
- QFileInfoGatherer fileInfoGatherer;
+ std::unique_ptr<QFileInfoGatherer> fileInfoGatherer;
#endif // filesystemwatcher
QTimer delayedSortTimer;
QHash<const QFileSystemNode*, bool> bypassFilters;
#if QT_CONFIG(regularexpression)
QStringList nameFilters;
+ std::vector<QRegularExpression> nameFiltersRegexps;
+ void rebuildNameFilterRegexps();
#endif
QHash<QString, QString> resolvedSymLinks;
diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp
index a972b7b106..8b3e381431 100644
--- a/src/gui/itemmodels/qstandarditemmodel.cpp
+++ b/src/gui/itemmodels/qstandarditemmodel.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qstandarditemmodel.h"
@@ -55,6 +19,11 @@
QT_BEGIN_NAMESPACE
+// Used internally to store the flags
+namespace {
+constexpr auto DataFlagsRole = Qt::ItemDataRole(Qt::UserRole - 1);
+}
+
static inline QString qStandardItemModelDataListMimeType()
{
return QStringLiteral("application/x-qstandarditemmodeldatalist");
@@ -311,14 +280,12 @@ void QStandardItemPrivate::setItemData(const QMap<int, QVariant> &roles)
/*!
\internal
*/
-const QMap<int, QVariant> QStandardItemPrivate::itemData() const
+QMap<int, QVariant> QStandardItemPrivate::itemData() const
{
QMap<int, QVariant> result;
- QList<QStandardItemData>::const_iterator it;
- for (it = values.cbegin(); it != values.cend(); ++it){
- // Qt::UserRole - 1 is used internally to store the flags
- if (it->role != Qt::UserRole - 1)
- result.insert(it->role, it->value);
+ for (const auto &data : values) {
+ if (data.role != DataFlagsRole)
+ result.insert(data.role, data.value);
}
return result;
}
@@ -355,11 +322,11 @@ void QStandardItemPrivate::sortChildren(int column, Qt::SortOrder order)
}
QModelIndexList changedPersistentIndexesFrom, changedPersistentIndexesTo;
- QList<QStandardItem*> sorted_children(children.count());
+ QList<QStandardItem*> sorted_children(children.size());
for (int i = 0; i < rowCount(); ++i) {
- int r = (i < sortable.count()
+ int r = (i < sortable.size()
? sortable.at(i).second
- : unsortable.at(i - sortable.count()));
+ : unsortable.at(i - sortable.size()));
for (int c = 0; c < columnCount(); ++c) {
QStandardItem *itm = q->child(r, c);
sorted_children[childIndex(i, c)] = itm;
@@ -407,7 +374,7 @@ void QStandardItemPrivate::setModel(QStandardItemModel *mod)
}
itm->d_func()->model = mod;
const QList<QStandardItem*> &childList = itm->d_func()->children;
- for (int i = 0; i < childList.count(); ++i) {
+ for (int i = 0; i < childList.size(); ++i) {
QStandardItem *chi = childList.at(i);
if (chi)
stack.push(chi);
@@ -468,7 +435,7 @@ bool QStandardItemPrivate::insertRows(int row, const QList<QStandardItem*> &item
Q_Q(QStandardItem);
if ((row < 0) || (row > rowCount()) || items.isEmpty())
return false;
- int count = items.count();
+ int count = items.size();
if (model)
model->d_func()->rowsAboutToBeInserted(q, row, row + count - 1);
if (rowCount() == 0) {
@@ -482,7 +449,7 @@ bool QStandardItemPrivate::insertRows(int row, const QList<QStandardItem*> &item
if (index != -1)
children.insert(index, columnCount() * count, nullptr);
}
- for (int i = 0; i < items.count(); ++i) {
+ for (int i = 0; i < items.size(); ++i) {
QStandardItem *item = items.at(i);
item->d_func()->model = model;
item->d_func()->parent = q;
@@ -514,7 +481,7 @@ bool QStandardItemPrivate::insertRows(int row, int count, const QList<QStandardI
}
if (!items.isEmpty()) {
int index = childIndex(row, 0);
- int limit = qMin(items.count(), columnCount() * count);
+ int limit = qMin(items.size(), columnCount() * count);
for (int i = 0; i < limit; ++i) {
QStandardItem *item = items.at(i);
if (item) {
@@ -559,7 +526,7 @@ bool QStandardItemPrivate::insertColumns(int column, int count, const QList<QSta
}
}
if (!items.isEmpty()) {
- int limit = qMin(items.count(), rowCount() * count);
+ int limit = qMin(items.size(), rowCount() * count);
for (int i = 0; i < limit; ++i) {
QStandardItem *item = items.at(i);
if (item) {
@@ -876,7 +843,7 @@ QStandardItem &QStandardItem::operator=(const QStandardItem &other)
QStandardItem::~QStandardItem()
{
Q_D(QStandardItem);
- for (QStandardItem *child : qAsConst(d->children)) {
+ for (QStandardItem *child : std::as_const(d->children)) {
if (child)
child->d_func()->setModel(nullptr);
delete child;
@@ -905,9 +872,15 @@ QStandardItem *QStandardItem::parent() const
Sets the item's data for the given \a role to the specified \a value.
If you subclass QStandardItem and reimplement this function, your
- reimplementation should call emitDataChanged() if you do not call
- the base implementation of setData(). This will ensure that e.g.
- views using the model are notified of the changes.
+ reimplementation should:
+ \list
+ \li call emitDataChanged() if you do not call the base implementation of
+ setData(). This will ensure that e.g. views using the model are notified
+ of the changes
+ \li call the base implementation for roles you don't handle, otherwise
+ setting flags, e.g. by calling setFlags(), setCheckable(), setEditable()
+ etc., will not work.
+ \endlist
\note The default implementation treats Qt::EditRole and Qt::DisplayRole
as referring to the same data.
@@ -961,6 +934,11 @@ void QStandardItem::clearData()
Returns the item's data for the given \a role, or an invalid
QVariant if there is no data for the role.
+ If you reimplement this function, your reimplementation should call
+ the base implementation for roles you don't handle, otherwise getting
+ flags, e.g. by calling flags(), isCheckable(), isEditable() etc.,
+ will not work.
+
\note The default implementation treats Qt::EditRole and Qt::DisplayRole
as referring to the same data.
*/
@@ -1020,7 +998,7 @@ void QStandardItem::emitDataChanged()
*/
void QStandardItem::setFlags(Qt::ItemFlags flags)
{
- setData((int)flags, Qt::UserRole - 1);
+ setData((int)flags, DataFlagsRole);
}
/*!
@@ -1035,7 +1013,7 @@ void QStandardItem::setFlags(Qt::ItemFlags flags)
*/
Qt::ItemFlags QStandardItem::flags() const
{
- QVariant v = data(Qt::UserRole - 1);
+ QVariant v = data(DataFlagsRole);
if (!v.isValid())
return (Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable
|Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled);
@@ -1624,8 +1602,8 @@ void QStandardItem::insertRow(int row, const QList<QStandardItem*> &items)
Q_D(QStandardItem);
if (row < 0)
return;
- if (columnCount() < items.count())
- setColumnCount(items.count());
+ if (columnCount() < items.size())
+ setColumnCount(items.size());
d->insertRows(row, 1, items);
}
@@ -1653,8 +1631,8 @@ void QStandardItem::insertColumn(int column, const QList<QStandardItem*> &items)
Q_D(QStandardItem);
if (column < 0)
return;
- if (rowCount() < items.count())
- setRowCount(items.count());
+ if (rowCount() < items.size())
+ setRowCount(items.size());
d->insertColumns(column, 1, items);
}
@@ -1893,10 +1871,37 @@ QStandardItem *QStandardItem::takeChild(int row, int column)
QStandardItem *item = nullptr;
int index = d->childIndex(row, column);
if (index != -1) {
+ QModelIndex changedIdx;
item = d->children.at(index);
- if (item)
- item->d_func()->setParentAndModel(nullptr, nullptr);
+ if (item) {
+ QStandardItemPrivate *const item_d = item->d_func();
+ if (d->model) {
+ QStandardItemModelPrivate *const model_d = d->model->d_func();
+ const int savedRows = item_d->rows;
+ const int savedCols = item_d->columns;
+ const QVector<QStandardItem*> savedChildren = item_d->children;
+ if (savedRows > 0) {
+ model_d->rowsAboutToBeRemoved(item, 0, savedRows - 1);
+ item_d->rows = 0;
+ item_d->children = QVector<QStandardItem*>(); //slightly faster than clear
+ model_d->rowsRemoved(item, 0, savedRows);
+ }
+ if (savedCols > 0) {
+ model_d->columnsAboutToBeRemoved(item, 0, savedCols - 1);
+ item_d->columns = 0;
+ item_d->children = QVector<QStandardItem*>(); //slightly faster than clear
+ model_d->columnsRemoved(item, 0, savedCols);
+ }
+ item_d->rows = savedRows;
+ item_d->columns = savedCols;
+ item_d->children = savedChildren;
+ changedIdx = d->model->indexFromItem(item);
+ }
+ item_d->setParentAndModel(nullptr, nullptr);
+ }
d->children.replace(index, nullptr);
+ if (changedIdx.isValid())
+ d->model->dataChanged(changedIdx, changedIdx);
}
return item;
}
@@ -2540,9 +2545,9 @@ QStandardItem *QStandardItemModel::verticalHeaderItem(int row) const
void QStandardItemModel::setHorizontalHeaderLabels(const QStringList &labels)
{
Q_D(QStandardItemModel);
- if (columnCount() < labels.count())
- setColumnCount(labels.count());
- for (int i = 0; i < labels.count(); ++i) {
+ if (columnCount() < labels.size())
+ setColumnCount(labels.size());
+ for (int i = 0; i < labels.size(); ++i) {
QStandardItem *item = horizontalHeaderItem(i);
if (!item) {
item = d->createItem();
@@ -2563,9 +2568,9 @@ void QStandardItemModel::setHorizontalHeaderLabels(const QStringList &labels)
void QStandardItemModel::setVerticalHeaderLabels(const QStringList &labels)
{
Q_D(QStandardItemModel);
- if (rowCount() < labels.count())
- setRowCount(labels.count());
- for (int i = 0; i < labels.count(); ++i) {
+ if (rowCount() < labels.size())
+ setRowCount(labels.size());
+ for (int i = 0; i < labels.size(); ++i) {
QStandardItem *item = verticalHeaderItem(i);
if (!item) {
item = d->createItem();
@@ -3111,21 +3116,21 @@ QStringList QStandardItemModel::mimeTypes() const
*/
QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
{
- QMimeData *data = QAbstractItemModel::mimeData(indexes);
+ std::unique_ptr<QMimeData> data(QAbstractItemModel::mimeData(indexes));
if (!data)
return nullptr;
const QString format = qStandardItemModelDataListMimeType();
if (!mimeTypes().contains(format))
- return data;
+ return data.release();
QByteArray encoded;
QDataStream stream(&encoded, QIODevice::WriteOnly);
QSet<QStandardItem*> itemsSet;
QStack<QStandardItem*> stack;
- itemsSet.reserve(indexes.count());
- stack.reserve(indexes.count());
- for (int i = 0; i < indexes.count(); ++i) {
+ itemsSet.reserve(indexes.size());
+ stack.reserve(indexes.size());
+ for (int i = 0; i < indexes.size(); ++i) {
if (QStandardItem *item = itemFromIndex(indexes.at(i))) {
itemsSet << item;
stack.push(item);
@@ -3135,7 +3140,7 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
}
}
- //remove duplicates childrens
+ //remove duplicates children
{
QDuplicateTracker<QStandardItem *> seen;
while (!stack.isEmpty()) {
@@ -3144,7 +3149,7 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
continue;
const QList<QStandardItem*> &childList = itm->d_func()->children;
- for (int i = 0; i < childList.count(); ++i) {
+ for (int i = 0; i < childList.size(); ++i) {
QStandardItem *chi = childList.at(i);
if (chi) {
itemsSet.remove(chi);
@@ -3154,8 +3159,8 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
}
}
- stack.reserve(itemsSet.count());
- for (QStandardItem *item : qAsConst(itemsSet))
+ stack.reserve(itemsSet.size());
+ for (QStandardItem *item : std::as_const(itemsSet))
stack.push(item);
//stream everything recursively
@@ -3164,12 +3169,12 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const
if (itemsSet.contains(item)) //if the item is selection 'top-level', stream its position
stream << item->row() << item->column();
- stream << *item << item->columnCount() << int(item->d_ptr->children.count());
+ stream << *item << item->columnCount() << int(item->d_ptr->children.size());
stack += item->d_ptr->children;
}
data->setData(format, encoded);
- return data;
+ return data.release();
}
@@ -3253,15 +3258,15 @@ bool QStandardItemModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
// Compute the number of continuous rows upon insertion and modify the rows to match
QList<int> rowsToInsert(bottom + 1);
- for (int i = 0; i < rows.count(); ++i)
+ for (int i = 0; i < rows.size(); ++i)
rowsToInsert[rows.at(i)] = 1;
- for (int i = 0; i < rowsToInsert.count(); ++i) {
+ for (int i = 0; i < rowsToInsert.size(); ++i) {
if (rowsToInsert.at(i) == 1){
rowsToInsert[i] = dragRowCount;
++dragRowCount;
}
}
- for (int i = 0; i < rows.count(); ++i)
+ for (int i = 0; i < rows.size(); ++i)
rows[i] = top + rowsToInsert.at(rows.at(i));
QBitArray isWrittenTo(dragRowCount * dragColumnCount);
diff --git a/src/gui/itemmodels/qstandarditemmodel.h b/src/gui/itemmodels/qstandarditemmodel.h
index 66ae3a27cd..a5ae05feeb 100644
--- a/src/gui/itemmodels/qstandarditemmodel.h
+++ b/src/gui/itemmodels/qstandarditemmodel.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSTANDARDITEMMODEL_H
#define QSTANDARDITEMMODEL_H
@@ -110,7 +74,7 @@ public:
inline void setFont(const QFont &font);
inline Qt::Alignment textAlignment() const {
- return Qt::Alignment(qvariant_cast<int>(data(Qt::TextAlignmentRole)));
+ return qvariant_cast<Qt::Alignment>(data(Qt::TextAlignmentRole));
}
inline void setTextAlignment(Qt::Alignment textAlignment);
@@ -143,43 +107,43 @@ public:
void setFlags(Qt::ItemFlags flags);
inline bool isEnabled() const {
- return (flags() & Qt::ItemIsEnabled) != 0;
+ return bool(flags() & Qt::ItemIsEnabled);
}
void setEnabled(bool enabled);
inline bool isEditable() const {
- return (flags() & Qt::ItemIsEditable) != 0;
+ return bool(flags() & Qt::ItemIsEditable);
}
void setEditable(bool editable);
inline bool isSelectable() const {
- return (flags() & Qt::ItemIsSelectable) != 0;
+ return bool(flags() & Qt::ItemIsSelectable);
}
void setSelectable(bool selectable);
inline bool isCheckable() const {
- return (flags() & Qt::ItemIsUserCheckable) != 0;
+ return bool(flags() & Qt::ItemIsUserCheckable);
}
void setCheckable(bool checkable);
inline bool isAutoTristate() const {
- return (flags() & Qt::ItemIsAutoTristate) != 0;
+ return bool(flags() & Qt::ItemIsAutoTristate);
}
void setAutoTristate(bool tristate);
inline bool isUserTristate() const {
- return (flags() & Qt::ItemIsUserTristate) != 0;
+ return bool(flags() & Qt::ItemIsUserTristate);
}
void setUserTristate(bool tristate);
#if QT_CONFIG(draganddrop)
inline bool isDragEnabled() const {
- return (flags() & Qt::ItemIsDragEnabled) != 0;
+ return bool(flags() & Qt::ItemIsDragEnabled);
}
void setDragEnabled(bool dragEnabled);
inline bool isDropEnabled() const {
- return (flags() & Qt::ItemIsDropEnabled) != 0;
+ return bool(flags() & Qt::ItemIsDropEnabled);
}
void setDropEnabled(bool dropEnabled);
#endif // QT_CONFIG(draganddrop)
@@ -274,7 +238,7 @@ inline void QStandardItem::setFont(const QFont &afont)
{ setData(afont, Qt::FontRole); }
inline void QStandardItem::setTextAlignment(Qt::Alignment atextAlignment)
-{ setData(int(atextAlignment), Qt::TextAlignmentRole); }
+{ setData(QVariant::fromValue(atextAlignment), Qt::TextAlignmentRole); }
inline void QStandardItem::setBackground(const QBrush &abrush)
{ setData(abrush, Qt::BackgroundRole); }
diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h
index 8a9a2c8d50..a0c3f8a161 100644
--- a/src/gui/itemmodels/qstandarditemmodel_p.h
+++ b/src/gui/itemmodels/qstandarditemmodel_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSTANDARDITEMMODEL_P_H
#define QSTANDARDITEMMODEL_P_H
@@ -51,6 +15,8 @@
// We mean it.
//
+#include <QtGui/qstandarditemmodel.h>
+
#include <QtGui/private/qtguiglobal_p.h>
#include "private/qabstractitemmodel_p.h"
@@ -68,8 +34,10 @@ class QStandardItemData
{
public:
inline QStandardItemData() : role(-1) {}
- inline QStandardItemData(int r, const QVariant &v) : role(r), value(v) {}
- inline QStandardItemData(const std::pair<const int&, const QVariant&> &p) : role(p.first), value(p.second) {}
+ inline QStandardItemData(int r, const QVariant &v) :
+ role(r == Qt::EditRole ? Qt::DisplayRole : r), value(v) {}
+ inline QStandardItemData(const std::pair<const int&, const QVariant&> &p) :
+ role(p.first == Qt::EditRole ? Qt::DisplayRole : p.first), value(p.second) {}
int role;
QVariant value;
inline bool operator==(const QStandardItemData &other) const { return role == other.role && value == other.value; }
@@ -137,7 +105,7 @@ public:
// backwards through the children
int backwardIter = childsLastIndexInParent - 1;
int forwardIter = childsLastIndexInParent;
- Q_FOREVER {
+ for (;;) {
if (forwardIter <= lastChild) {
if (children.at(forwardIter) == child) {
childsLastIndexInParent = forwardIter;
@@ -180,7 +148,7 @@ public:
void changeFlags(bool enable, Qt::ItemFlags f);
void setItemData(const QMap<int, QVariant> &roles);
- const QMap<int, QVariant> itemData() const;
+ QMap<int, QVariant> itemData() const;
bool insertRows(int row, int count, const QList<QStandardItem*> &items);
bool insertRows(int row, const QList<QStandardItem*> &items);