forked from qt-creator/qt-creator
filepath: Move FileUtils:: function out of FilePath.cpp
Change-Id: If78c349b0145b86a76cd033e4dbc30b237ad917b Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -65,12 +65,6 @@ namespace Utils {
|
||||
|
||||
static DeviceFileHooks s_deviceHooks;
|
||||
|
||||
/*! \class Utils::FileUtils
|
||||
|
||||
\brief The FileUtils class contains file and directory related convenience
|
||||
functions.
|
||||
|
||||
*/
|
||||
|
||||
static bool removeRecursivelyLocal(const FilePath &filePath, QString *error)
|
||||
{
|
||||
@@ -78,9 +72,11 @@ static bool removeRecursivelyLocal(const FilePath &filePath, QString *error)
|
||||
QFileInfo fileInfo = filePath.toFileInfo();
|
||||
if (!fileInfo.exists() && !fileInfo.isSymLink())
|
||||
return true;
|
||||
QFile::setPermissions(filePath.toString(), fileInfo.permissions() | QFile::WriteUser);
|
||||
|
||||
QFile::setPermissions(fileInfo.absoluteFilePath(), fileInfo.permissions() | QFile::WriteUser);
|
||||
|
||||
if (fileInfo.isDir()) {
|
||||
QDir dir(filePath.toString());
|
||||
QDir dir(fileInfo.absoluteFilePath());
|
||||
dir.setPath(dir.canonicalPath());
|
||||
if (dir.isRoot()) {
|
||||
if (error) {
|
||||
@@ -122,85 +118,9 @@ static bool removeRecursivelyLocal(const FilePath &filePath, QString *error)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Cleans part after optional :// scheme separator, similar to QDir::cleanPath()
|
||||
// - directory separators normalized (that is, platform-native
|
||||
// separators converted to "/") and redundant ones removed, and "."s and ".."s
|
||||
// resolved (as far as possible).
|
||||
// Symbolic links are kept. This function does not return the
|
||||
// canonical path, but rather the simplest version of the input.
|
||||
// For example, "./local" becomes "local", "local/../bin" becomes
|
||||
// "bin" and "/local/usr/../bin" becomes "/local/bin".
|
||||
|
||||
// FIXME: This should not use the host-platform dependent QDir::cleanPath()
|
||||
|
||||
static QString doCleanPath(const QString &input)
|
||||
void FilePath::setDeviceFileHooks(const DeviceFileHooks &hooks)
|
||||
{
|
||||
const int pos = input.indexOf("://");
|
||||
if (pos == -1)
|
||||
return QDir::cleanPath(input);
|
||||
return input.left(pos + 3) + QDir::cleanPath(input.mid(pos + 3));
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies the directory specified by \a srcFilePath recursively to \a tgtFilePath. \a tgtFilePath will contain
|
||||
the target directory, which will be created. Example usage:
|
||||
|
||||
\code
|
||||
QString error;
|
||||
bool ok = Utils::FileUtils::copyRecursively("/foo/bar", "/foo/baz", &error);
|
||||
if (!ok)
|
||||
qDebug() << error;
|
||||
\endcode
|
||||
|
||||
This will copy the contents of /foo/bar into to the baz directory under /foo, which will be created in the process.
|
||||
|
||||
\note The \a error parameter is optional.
|
||||
|
||||
Returns whether the operation succeeded.
|
||||
*/
|
||||
|
||||
bool FileUtils::copyRecursively(const FilePath &srcFilePath, const FilePath &tgtFilePath, QString *error)
|
||||
{
|
||||
return copyRecursively(
|
||||
srcFilePath, tgtFilePath, error, [](const FilePath &src, const FilePath &dest, QString *error) {
|
||||
if (!src.copyFile(dest)) {
|
||||
if (error) {
|
||||
*error = QCoreApplication::translate("Utils::FileUtils",
|
||||
"Could not copy file \"%1\" to \"%2\".")
|
||||
.arg(src.toUserOutput(), dest.toUserOutput());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies a file specified by \a srcFilePath to \a tgtFilePath only if \a srcFilePath is different
|
||||
(file contents and last modification time).
|
||||
|
||||
Returns whether the operation succeeded.
|
||||
*/
|
||||
|
||||
bool FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath)
|
||||
{
|
||||
QTC_ASSERT(srcFilePath.exists(), return false);
|
||||
QTC_ASSERT(srcFilePath.scheme() == tgtFilePath.scheme(), return false);
|
||||
QTC_ASSERT(srcFilePath.host() == tgtFilePath.host(), return false);
|
||||
|
||||
if (tgtFilePath.exists()) {
|
||||
const QDateTime srcModified = srcFilePath.lastModified();
|
||||
const QDateTime tgtModified = tgtFilePath.lastModified();
|
||||
if (srcModified == tgtModified) {
|
||||
const QByteArray srcContents = srcFilePath.fileContents();
|
||||
const QByteArray tgtContents = srcFilePath.fileContents();
|
||||
if (srcContents == tgtContents)
|
||||
return true;
|
||||
}
|
||||
tgtFilePath.removeFile();
|
||||
}
|
||||
|
||||
return srcFilePath.copyFile(tgtFilePath);
|
||||
s_deviceHooks = hooks;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -314,85 +234,6 @@ QString FilePath::shortNativePath() const
|
||||
return toUserOutput();
|
||||
}
|
||||
|
||||
QString FileUtils::fileSystemFriendlyName(const QString &name)
|
||||
{
|
||||
QString result = name;
|
||||
result.replace(QRegularExpression(QLatin1String("\\W")), QLatin1String("_"));
|
||||
result.replace(QRegularExpression(QLatin1String("_+")), QLatin1String("_")); // compact _
|
||||
result.remove(QRegularExpression(QLatin1String("^_*"))); // remove leading _
|
||||
result.remove(QRegularExpression(QLatin1String("_+$"))); // remove trailing _
|
||||
if (result.isEmpty())
|
||||
result = QLatin1String("unknown");
|
||||
return result;
|
||||
}
|
||||
|
||||
int FileUtils::indexOfQmakeUnfriendly(const QString &name, int startpos)
|
||||
{
|
||||
static const QRegularExpression checkRegExp(QLatin1String("[^a-zA-Z0-9_.-]"));
|
||||
return checkRegExp.match(name, startpos).capturedStart();
|
||||
}
|
||||
|
||||
QString FileUtils::qmakeFriendlyName(const QString &name)
|
||||
{
|
||||
QString result = name;
|
||||
|
||||
// Remove characters that might trip up a build system (especially qmake):
|
||||
int pos = indexOfQmakeUnfriendly(result);
|
||||
while (pos >= 0) {
|
||||
result[pos] = QLatin1Char('_');
|
||||
pos = indexOfQmakeUnfriendly(result, pos);
|
||||
}
|
||||
return fileSystemFriendlyName(result);
|
||||
}
|
||||
|
||||
bool FileUtils::makeWritable(const FilePath &path)
|
||||
{
|
||||
return path.setPermissions(path.permissions() | QFile::WriteUser);
|
||||
}
|
||||
|
||||
// makes sure that capitalization of directories is canonical on Windows and OS X.
|
||||
// This mimics the logic in QDeclarative_isFileCaseCorrect
|
||||
QString FileUtils::normalizedPathName(const QString &name)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
const QString nativeSeparatorName(QDir::toNativeSeparators(name));
|
||||
const auto nameC = reinterpret_cast<LPCTSTR>(nativeSeparatorName.utf16()); // MinGW
|
||||
PIDLIST_ABSOLUTE file;
|
||||
HRESULT hr = SHParseDisplayName(nameC, NULL, &file, 0, NULL);
|
||||
if (FAILED(hr))
|
||||
return name;
|
||||
TCHAR buffer[MAX_PATH];
|
||||
const bool success = SHGetPathFromIDList(file, buffer);
|
||||
ILFree(file);
|
||||
return success ? QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const ushort *>(buffer)))
|
||||
: name;
|
||||
#elif defined(Q_OS_OSX)
|
||||
return Internal::normalizePathName(name);
|
||||
#else // do not try to handle case-insensitive file systems on Linux
|
||||
return name;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool isRelativePathHelper(const QString &path, OsType osType)
|
||||
{
|
||||
if (path.startsWith('/'))
|
||||
return false;
|
||||
if (osType == OsType::OsTypeWindows) {
|
||||
if (path.startsWith('\\'))
|
||||
return false;
|
||||
// Unlike QFileInfo, this won't accept a relative path with a drive letter.
|
||||
// Such paths result in a royal mess anyway ...
|
||||
if (path.length() >= 3 && path.at(1) == ':' && path.at(0).isLetter()
|
||||
&& (path.at(2) == '/' || path.at(2) == '\\'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileUtils::isRelativePath(const QString &path)
|
||||
{
|
||||
return isRelativePathHelper(path, HostOsInfo::hostOs());
|
||||
}
|
||||
|
||||
bool FilePath::isRelativePath() const
|
||||
{
|
||||
@@ -422,20 +263,6 @@ FilePath FilePath::cleanPath() const
|
||||
return result;
|
||||
}
|
||||
|
||||
FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &filePath)
|
||||
{
|
||||
FilePath newCommonPath = oldCommonPath;
|
||||
while (!newCommonPath.isEmpty() && !filePath.isChildOf(newCommonPath))
|
||||
newCommonPath = newCommonPath.parentDir();
|
||||
return newCommonPath.canonicalPath();
|
||||
}
|
||||
|
||||
FilePath FileUtils::homePath()
|
||||
{
|
||||
return FilePath::fromString(doCleanPath(QDir::homePath()));
|
||||
}
|
||||
|
||||
|
||||
/*! \class Utils::FilePath
|
||||
|
||||
\brief The FilePath class is an abstraction for handles to objects
|
||||
@@ -597,11 +424,6 @@ QUrl FilePath::toUrl() const
|
||||
return url;
|
||||
}
|
||||
|
||||
void FileUtils::setDeviceFileHooks(const DeviceFileHooks &hooks)
|
||||
{
|
||||
s_deviceHooks = hooks;
|
||||
}
|
||||
|
||||
/// \returns a QString to display to the user, including the device prefix
|
||||
/// Converts the separators to the native format of the system
|
||||
/// this path belongs to.
|
||||
@@ -1175,13 +997,11 @@ void FilePath::setFromString(const QString &filename)
|
||||
}
|
||||
|
||||
m_data = "/";
|
||||
|
||||
} else {
|
||||
m_scheme.clear();
|
||||
m_host.clear();
|
||||
m_data = filename;
|
||||
return;
|
||||
}
|
||||
|
||||
m_scheme.clear();
|
||||
m_host.clear();
|
||||
m_data = filename;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,7 @@ class tst_fileutils; // This becomes a friend of Utils::FilePath for testing pri
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class DeviceFileHooks;
|
||||
class Environment;
|
||||
class EnvironmentChange;
|
||||
|
||||
@@ -222,6 +223,8 @@ public:
|
||||
[[nodiscard]] static QString specialPath(SpecialPathComponent component);
|
||||
[[nodiscard]] static FilePath specialFilePath(SpecialPathComponent component);
|
||||
|
||||
static void setDeviceFileHooks(const DeviceFileHooks &hooks);
|
||||
|
||||
private:
|
||||
friend class ::tst_fileutils;
|
||||
static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath);
|
||||
@@ -238,6 +241,47 @@ inline size_t qHash(const Utils::FilePath &a, uint seed = 0)
|
||||
return a.hash(seed);
|
||||
}
|
||||
|
||||
class DeviceFileHooks
|
||||
{
|
||||
public:
|
||||
std::function<bool(const FilePath &)> isExecutableFile;
|
||||
std::function<bool(const FilePath &)> isReadableFile;
|
||||
std::function<bool(const FilePath &)> isReadableDir;
|
||||
std::function<bool(const FilePath &)> isWritableDir;
|
||||
std::function<bool(const FilePath &)> isWritableFile;
|
||||
std::function<bool(const FilePath &)> isFile;
|
||||
std::function<bool(const FilePath &)> isDir;
|
||||
std::function<bool(const FilePath &)> ensureWritableDir;
|
||||
std::function<bool(const FilePath &)> ensureExistingFile;
|
||||
std::function<bool(const FilePath &)> createDir;
|
||||
std::function<bool(const FilePath &)> exists;
|
||||
std::function<bool(const FilePath &)> removeFile;
|
||||
std::function<bool(const FilePath &)> removeRecursively;
|
||||
std::function<bool(const FilePath &, const FilePath &)> copyFile;
|
||||
std::function<bool(const FilePath &, const FilePath &)> renameFile;
|
||||
std::function<FilePath(const FilePath &, const FilePaths &)> searchInPath;
|
||||
std::function<FilePath(const FilePath &)> symLinkTarget;
|
||||
std::function<QString(const FilePath &)> mapToDevicePath;
|
||||
std::function<void(const FilePath &,
|
||||
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
|
||||
const FileFilter &)> iterateDirectory;
|
||||
std::function<QByteArray(const FilePath &, qint64, qint64)> fileContents;
|
||||
std::function<bool(const FilePath &, const QByteArray &)> writeFileContents;
|
||||
std::function<QDateTime(const FilePath &)> lastModified;
|
||||
std::function<QFile::Permissions(const FilePath &)> permissions;
|
||||
std::function<bool(const FilePath &, QFile::Permissions)> setPermissions;
|
||||
std::function<OsType(const FilePath &)> osType;
|
||||
std::function<Environment(const FilePath &)> environment;
|
||||
std::function<qint64(const FilePath &)> fileSize;
|
||||
std::function<qint64(const FilePath &)> bytesAvailable;
|
||||
std::function<QString(const FilePath &)> deviceDisplayName;
|
||||
|
||||
template <class ...Args> using Continuation = std::function<void(Args...)>;
|
||||
std::function<void(const Continuation<bool> &, const FilePath &, const FilePath &)> asyncCopyFile;
|
||||
std::function<void(const Continuation<const QByteArray &> &, const FilePath &, qint64, qint64)> asyncFileContents;
|
||||
std::function<void(const Continuation<bool> &, const FilePath &, const QByteArray &)> asyncWriteFileContents;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -254,4 +298,5 @@ struct QTCREATOR_UTILS_EXPORT hash<Utils::FilePath>
|
||||
using result_type = size_t;
|
||||
result_type operator()(const argument_type &fn) const;
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "qtcassert.h"
|
||||
#include "hostosinfo.h"
|
||||
|
||||
#include "fsengine/fileiconprovider.h"
|
||||
#include "fsengine/fsengine.h"
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QOperatingSystemVersion>
|
||||
#include <QRegularExpression>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
#include <QXmlStreamWriter>
|
||||
@@ -285,6 +287,13 @@ TempFileSaver::~TempFileSaver()
|
||||
QFile::remove(m_filePath.toString());
|
||||
}
|
||||
|
||||
/*! \class Utils::FileUtils
|
||||
|
||||
\brief The FileUtils class contains file and directory related convenience
|
||||
functions.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef QT_GUI_LIB
|
||||
FileUtils::CopyAskingForOverwrite::CopyAskingForOverwrite(QWidget *dialogParent, const std::function<void (FilePath)> &postOperation)
|
||||
: m_parent(dialogParent)
|
||||
@@ -629,4 +638,178 @@ void FileUtils::iterateLsOutput(const FilePath &base,
|
||||
|
||||
#endif // QT_WIDGETS_LIB
|
||||
|
||||
/*!
|
||||
Copies the directory specified by \a srcFilePath recursively to \a tgtFilePath. \a tgtFilePath will contain
|
||||
the target directory, which will be created. Example usage:
|
||||
|
||||
\code
|
||||
QString error;
|
||||
bool ok = Utils::FileUtils::copyRecursively("/foo/bar", "/foo/baz", &error);
|
||||
if (!ok)
|
||||
qDebug() << error;
|
||||
\endcode
|
||||
|
||||
This will copy the contents of /foo/bar into to the baz directory under /foo, which will be created in the process.
|
||||
|
||||
\note The \a error parameter is optional.
|
||||
|
||||
Returns whether the operation succeeded.
|
||||
*/
|
||||
|
||||
bool FileUtils::copyRecursively(const FilePath &srcFilePath, const FilePath &tgtFilePath, QString *error)
|
||||
{
|
||||
return copyRecursively(
|
||||
srcFilePath, tgtFilePath, error, [](const FilePath &src, const FilePath &dest, QString *error) {
|
||||
if (!src.copyFile(dest)) {
|
||||
if (error) {
|
||||
*error = QCoreApplication::translate("Utils::FileUtils",
|
||||
"Could not copy file \"%1\" to \"%2\".")
|
||||
.arg(src.toUserOutput(), dest.toUserOutput());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies a file specified by \a srcFilePath to \a tgtFilePath only if \a srcFilePath is different
|
||||
(file contents and last modification time).
|
||||
|
||||
Returns whether the operation succeeded.
|
||||
*/
|
||||
|
||||
bool FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath)
|
||||
{
|
||||
QTC_ASSERT(srcFilePath.exists(), return false);
|
||||
QTC_ASSERT(srcFilePath.scheme() == tgtFilePath.scheme(), return false);
|
||||
QTC_ASSERT(srcFilePath.host() == tgtFilePath.host(), return false);
|
||||
|
||||
if (tgtFilePath.exists()) {
|
||||
const QDateTime srcModified = srcFilePath.lastModified();
|
||||
const QDateTime tgtModified = tgtFilePath.lastModified();
|
||||
if (srcModified == tgtModified) {
|
||||
const QByteArray srcContents = srcFilePath.fileContents();
|
||||
const QByteArray tgtContents = srcFilePath.fileContents();
|
||||
if (srcContents == tgtContents)
|
||||
return true;
|
||||
}
|
||||
tgtFilePath.removeFile();
|
||||
}
|
||||
|
||||
return srcFilePath.copyFile(tgtFilePath);
|
||||
}
|
||||
|
||||
QString FileUtils::fileSystemFriendlyName(const QString &name)
|
||||
{
|
||||
QString result = name;
|
||||
result.replace(QRegularExpression(QLatin1String("\\W")), QLatin1String("_"));
|
||||
result.replace(QRegularExpression(QLatin1String("_+")), QLatin1String("_")); // compact _
|
||||
result.remove(QRegularExpression(QLatin1String("^_*"))); // remove leading _
|
||||
result.remove(QRegularExpression(QLatin1String("_+$"))); // remove trailing _
|
||||
if (result.isEmpty())
|
||||
result = QLatin1String("unknown");
|
||||
return result;
|
||||
}
|
||||
|
||||
int FileUtils::indexOfQmakeUnfriendly(const QString &name, int startpos)
|
||||
{
|
||||
static const QRegularExpression checkRegExp(QLatin1String("[^a-zA-Z0-9_.-]"));
|
||||
return checkRegExp.match(name, startpos).capturedStart();
|
||||
}
|
||||
|
||||
QString FileUtils::qmakeFriendlyName(const QString &name)
|
||||
{
|
||||
QString result = name;
|
||||
|
||||
// Remove characters that might trip up a build system (especially qmake):
|
||||
int pos = indexOfQmakeUnfriendly(result);
|
||||
while (pos >= 0) {
|
||||
result[pos] = QLatin1Char('_');
|
||||
pos = indexOfQmakeUnfriendly(result, pos);
|
||||
}
|
||||
return fileSystemFriendlyName(result);
|
||||
}
|
||||
|
||||
bool FileUtils::makeWritable(const FilePath &path)
|
||||
{
|
||||
return path.setPermissions(path.permissions() | QFile::WriteUser);
|
||||
}
|
||||
|
||||
// makes sure that capitalization of directories is canonical on Windows and macOS.
|
||||
// This mimics the logic in QDeclarative_isFileCaseCorrect
|
||||
QString FileUtils::normalizedPathName(const QString &name)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
const QString nativeSeparatorName(QDir::toNativeSeparators(name));
|
||||
const auto nameC = reinterpret_cast<LPCTSTR>(nativeSeparatorName.utf16()); // MinGW
|
||||
PIDLIST_ABSOLUTE file;
|
||||
HRESULT hr = SHParseDisplayName(nameC, NULL, &file, 0, NULL);
|
||||
if (FAILED(hr))
|
||||
return name;
|
||||
TCHAR buffer[MAX_PATH];
|
||||
const bool success = SHGetPathFromIDList(file, buffer);
|
||||
ILFree(file);
|
||||
return success ? QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const ushort *>(buffer)))
|
||||
: name;
|
||||
#elif defined(Q_OS_MACOS)
|
||||
return Internal::normalizePathName(name);
|
||||
#else // do not try to handle case-insensitive file systems on Linux
|
||||
return name;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isRelativePathHelper(const QString &path, OsType osType)
|
||||
{
|
||||
if (path.startsWith('/'))
|
||||
return false;
|
||||
if (osType == OsType::OsTypeWindows) {
|
||||
if (path.startsWith('\\'))
|
||||
return false;
|
||||
// Unlike QFileInfo, this won't accept a relative path with a drive letter.
|
||||
// Such paths result in a royal mess anyway ...
|
||||
if (path.length() >= 3 && path.at(1) == ':' && path.at(0).isLetter()
|
||||
&& (path.at(2) == '/' || path.at(2) == '\\'))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileUtils::isRelativePath(const QString &path)
|
||||
{
|
||||
return isRelativePathHelper(path, HostOsInfo::hostOs());
|
||||
}
|
||||
|
||||
// Cleans part after optional :// scheme separator, similar to QDir::cleanPath()
|
||||
// - directory separators normalized (that is, platform-native
|
||||
// separators converted to "/") and redundant ones removed, and "."s and ".."s
|
||||
// resolved (as far as possible).
|
||||
// Symbolic links are kept. This function does not return the
|
||||
// canonical path, but rather the simplest version of the input.
|
||||
// For example, "./local" becomes "local", "local/../bin" becomes
|
||||
// "bin" and "/local/usr/../bin" becomes "/local/bin".
|
||||
|
||||
// FIXME: This should not use the host-platform dependent QDir::cleanPath()
|
||||
|
||||
QString doCleanPath(const QString &input)
|
||||
{
|
||||
const int pos = input.indexOf("://");
|
||||
if (pos == -1)
|
||||
return QDir::cleanPath(input);
|
||||
return input.left(pos + 3) + QDir::cleanPath(input.mid(pos + 3));
|
||||
}
|
||||
|
||||
FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &filePath)
|
||||
{
|
||||
FilePath newCommonPath = oldCommonPath;
|
||||
while (!newCommonPath.isEmpty() && !filePath.isChildOf(newCommonPath))
|
||||
newCommonPath = newCommonPath.parentDir();
|
||||
return newCommonPath.canonicalPath();
|
||||
}
|
||||
|
||||
FilePath FileUtils::homePath()
|
||||
{
|
||||
return FilePath::fromString(doCleanPath(QDir::homePath()));
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -53,47 +53,6 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class DeviceFileHooks
|
||||
{
|
||||
public:
|
||||
std::function<bool(const FilePath &)> isExecutableFile;
|
||||
std::function<bool(const FilePath &)> isReadableFile;
|
||||
std::function<bool(const FilePath &)> isReadableDir;
|
||||
std::function<bool(const FilePath &)> isWritableDir;
|
||||
std::function<bool(const FilePath &)> isWritableFile;
|
||||
std::function<bool(const FilePath &)> isFile;
|
||||
std::function<bool(const FilePath &)> isDir;
|
||||
std::function<bool(const FilePath &)> ensureWritableDir;
|
||||
std::function<bool(const FilePath &)> ensureExistingFile;
|
||||
std::function<bool(const FilePath &)> createDir;
|
||||
std::function<bool(const FilePath &)> exists;
|
||||
std::function<bool(const FilePath &)> removeFile;
|
||||
std::function<bool(const FilePath &)> removeRecursively;
|
||||
std::function<bool(const FilePath &, const FilePath &)> copyFile;
|
||||
std::function<bool(const FilePath &, const FilePath &)> renameFile;
|
||||
std::function<FilePath(const FilePath &, const FilePaths &)> searchInPath;
|
||||
std::function<FilePath(const FilePath &)> symLinkTarget;
|
||||
std::function<QString(const FilePath &)> mapToDevicePath;
|
||||
std::function<void(const FilePath &,
|
||||
const std::function<bool(const FilePath &)> &, // Abort on 'false' return.
|
||||
const FileFilter &)> iterateDirectory;
|
||||
std::function<QByteArray(const FilePath &, qint64, qint64)> fileContents;
|
||||
std::function<bool(const FilePath &, const QByteArray &)> writeFileContents;
|
||||
std::function<QDateTime(const FilePath &)> lastModified;
|
||||
std::function<QFile::Permissions(const FilePath &)> permissions;
|
||||
std::function<bool(const FilePath &, QFile::Permissions)> setPermissions;
|
||||
std::function<OsType(const FilePath &)> osType;
|
||||
std::function<Environment(const FilePath &)> environment;
|
||||
std::function<qint64(const FilePath &)> fileSize;
|
||||
std::function<qint64(const FilePath &)> bytesAvailable;
|
||||
std::function<QString(const FilePath &)> deviceDisplayName;
|
||||
|
||||
template <class ...Args> using Continuation = std::function<void(Args...)>;
|
||||
std::function<void(const Continuation<bool> &, const FilePath &, const FilePath &)> asyncCopyFile;
|
||||
std::function<void(const Continuation<const QByteArray &> &, const FilePath &, qint64, qint64)> asyncFileContents;
|
||||
std::function<void(const Continuation<bool> &, const FilePath &, const QByteArray &)> asyncWriteFileContents;
|
||||
};
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT FileUtils
|
||||
{
|
||||
public:
|
||||
@@ -138,8 +97,6 @@ public:
|
||||
static QByteArray fileId(const FilePath &fileName);
|
||||
static FilePath homePath();
|
||||
|
||||
static void setDeviceFileHooks(const DeviceFileHooks &hooks);
|
||||
|
||||
static void iterateLsOutput(const FilePath &base,
|
||||
const QStringList &entries,
|
||||
const FileFilter &filter,
|
||||
@@ -328,5 +285,8 @@ private:
|
||||
|
||||
QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FilePath &fn);
|
||||
|
||||
bool isRelativePathHelper(const QString &path, OsType osType);
|
||||
QString doCleanPath(const QString &input);
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
|
@@ -610,7 +610,7 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
|
||||
return device->displayName();
|
||||
};
|
||||
|
||||
FileUtils::setDeviceFileHooks(deviceHooks);
|
||||
FilePath::setDeviceFileHooks(deviceHooks);
|
||||
|
||||
DeviceProcessHooks processHooks;
|
||||
|
||||
|
@@ -175,7 +175,7 @@ void tst_fsengine::initTestCase()
|
||||
|
||||
deviceHooks.mapToDevicePath = [](const FilePath &filePath) { return filePath.path(); };
|
||||
|
||||
FileUtils::setDeviceFileHooks(deviceHooks);
|
||||
FilePath::setDeviceFileHooks(deviceHooks);
|
||||
|
||||
FSEngine::addDevice(FilePath::fromString("device://test"));
|
||||
|
||||
|
Reference in New Issue
Block a user