forked from qt-creator/qt-creator
FilePath: Prepare for implementation some remote functions
The callback will be set from DeviceManager to re-route the implementation through matching IDevice instances. Change-Id: Ib210504008b8a3471452448a98378d4902e2cadf Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -62,6 +62,8 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
|
static DeviceFileHooks s_deviceHooks;
|
||||||
|
|
||||||
/*! \class Utils::CommandLine
|
/*! \class Utils::CommandLine
|
||||||
|
|
||||||
\brief The CommandLine class represents a command line of a QProcess
|
\brief The CommandLine class represents a command line of a QProcess
|
||||||
@@ -318,6 +320,17 @@ FilePath FilePath::operator/(const QString &str) const
|
|||||||
return pathAppended(str);
|
return pathAppended(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilePath::clear()
|
||||||
|
{
|
||||||
|
m_data.clear();
|
||||||
|
m_url.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilePath::isEmpty() const
|
||||||
|
{
|
||||||
|
return m_data.isEmpty() && !m_url.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Like QDir::toNativeSeparators(), but use prefix '~' instead of $HOME on unix systems when an
|
Like QDir::toNativeSeparators(), but use prefix '~' instead of $HOME on unix systems when an
|
||||||
absolute path is given.
|
absolute path is given.
|
||||||
@@ -421,6 +434,13 @@ FilePath FilePath::resolvePath(const QString &fileName) const
|
|||||||
return FilePath::fromString(QDir::cleanPath(toString() + QLatin1Char('/') + fileName));
|
return FilePath::fromString(QDir::cleanPath(toString() + QLatin1Char('/') + fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePath FilePath::resolveSymlinkTarget() const
|
||||||
|
{
|
||||||
|
// FIXME: implement
|
||||||
|
QTC_CHECK(false);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &filePath)
|
FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &filePath)
|
||||||
{
|
{
|
||||||
FilePath newCommonPath = oldCommonPath;
|
FilePath newCommonPath = oldCommonPath;
|
||||||
@@ -737,6 +757,11 @@ QUrl FilePath::toUrl() const
|
|||||||
return m_url;
|
return m_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FilePath::setDeviceFileHooks(const DeviceFileHooks &hooks)
|
||||||
|
{
|
||||||
|
s_deviceHooks = hooks;
|
||||||
|
}
|
||||||
|
|
||||||
/// \returns a QString to display to the user
|
/// \returns a QString to display to the user
|
||||||
/// Converts the separators to the native format
|
/// Converts the separators to the native format
|
||||||
QString FilePath::toUserOutput() const
|
QString FilePath::toUserOutput() const
|
||||||
@@ -777,20 +802,117 @@ QString FilePath::fileNameWithPathComponents(int pathComponents) const
|
|||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FilePath::path() const
|
||||||
|
{
|
||||||
|
if (!m_data.isEmpty())
|
||||||
|
return m_data;
|
||||||
|
return m_url.path();
|
||||||
|
}
|
||||||
|
|
||||||
/// \returns a bool indicating whether a file with this
|
/// \returns a bool indicating whether a file with this
|
||||||
/// FilePath exists.
|
/// FilePath exists.
|
||||||
bool FilePath::exists() const
|
bool FilePath::exists() const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(!needsDevice(), return false);
|
||||||
return !isEmpty() && QFileInfo::exists(m_data);
|
return !isEmpty() && QFileInfo::exists(m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// \returns a bool indicating whether a path is writable.
|
/// \returns a bool indicating whether a path is writable.
|
||||||
bool FilePath::isWritablePath() const
|
bool FilePath::isWritableDir() const
|
||||||
{
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.isWritableDir, return false);
|
||||||
|
return s_deviceHooks.isReadableFile(*this);
|
||||||
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return exists() && fi.isDir() && fi.isWritable();
|
return exists() && fi.isDir() && fi.isWritable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FilePath::isExecutableFile() const
|
||||||
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.isExecutableFile, return false);
|
||||||
|
return s_deviceHooks.isExecutableFile(*this);
|
||||||
|
}
|
||||||
|
const QFileInfo fi{m_data};
|
||||||
|
return fi.exists() && fi.isExecutable() && !fi.isDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilePath::isReadableFile() const
|
||||||
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.isReadableFile, return false);
|
||||||
|
return s_deviceHooks.isReadableFile(*this);
|
||||||
|
}
|
||||||
|
const QFileInfo fi{m_data};
|
||||||
|
return fi.exists() && fi.isReadable() && !fi.isDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilePath::isReadableDir() const
|
||||||
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.isReadableDir, return false);
|
||||||
|
return s_deviceHooks.isReadableDir(*this);
|
||||||
|
}
|
||||||
|
const QFileInfo fi{m_data};
|
||||||
|
return fi.exists() && fi.isReadable() && fi.isDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilePath::createDir() const
|
||||||
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.createDir, return false);
|
||||||
|
return s_deviceHooks.createDir(*this);
|
||||||
|
}
|
||||||
|
QDir dir(m_data);
|
||||||
|
return dir.mkpath(dir.absolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<FilePath> FilePath::dirEntries(const QStringList &nameFilters, QDir::Filters filters) const
|
||||||
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.dirEntries, return {});
|
||||||
|
return s_deviceHooks.dirEntries(*this, nameFilters, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QFileInfoList entryInfoList = QDir(toString()).entryInfoList(nameFilters, filters);
|
||||||
|
return Utils::transform(entryInfoList, &FilePath::fromFileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<FilePath> FilePath::dirEntries(QDir::Filters filters) const
|
||||||
|
{
|
||||||
|
return dirEntries({}, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FilePath::fileContents(int maxSize) const
|
||||||
|
{
|
||||||
|
if (needsDevice()) {
|
||||||
|
QTC_ASSERT(s_deviceHooks.fileContents, return {});
|
||||||
|
return s_deviceHooks.fileContents(*this, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString path = toString();
|
||||||
|
QFile f(path);
|
||||||
|
if (!f.exists())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (!f.open(QFile::ReadOnly))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (maxSize != -1)
|
||||||
|
return f.read(maxSize);
|
||||||
|
|
||||||
|
return f.readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilePath::needsDevice() const
|
||||||
|
{
|
||||||
|
return m_url.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Find the parent directory of a given directory.
|
/// Find the parent directory of a given directory.
|
||||||
|
|
||||||
/// Returns an empty FilePath if the current directory is already
|
/// Returns an empty FilePath if the current directory is already
|
||||||
@@ -1072,14 +1194,46 @@ QString FilePath::calcRelativePath(const QString &absolutePath, const QString &a
|
|||||||
return relativePath;
|
return relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePath FilePath::onDevice(const FilePath &deviceTemplate) const
|
||||||
|
{
|
||||||
|
FilePath res = *this;
|
||||||
|
|
||||||
|
if (res.m_url.isValid()) {
|
||||||
|
if (deviceTemplate.m_url.isValid()) {
|
||||||
|
const QString path = m_url.path();
|
||||||
|
res.m_url = deviceTemplate.toUrl();
|
||||||
|
res.m_url.setPath(path);
|
||||||
|
} else {
|
||||||
|
res.m_data = deviceTemplate.m_data;
|
||||||
|
res.m_url.clear();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (deviceTemplate.m_url.isValid()) {
|
||||||
|
res.m_url = deviceTemplate.m_url;
|
||||||
|
res.m_url.setPath(m_data);
|
||||||
|
res.m_data.clear();
|
||||||
|
} else {
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
FilePath FilePath::pathAppended(const QString &str) const
|
FilePath FilePath::pathAppended(const QString &str) const
|
||||||
{
|
{
|
||||||
FilePath fn = *this;
|
FilePath fn = *this;
|
||||||
if (str.isEmpty())
|
if (str.isEmpty())
|
||||||
return fn;
|
return fn;
|
||||||
if (!isEmpty() && !m_data.endsWith(QLatin1Char('/')))
|
if (fn.m_url.isValid()) {
|
||||||
fn.m_data.append('/');
|
QString path = fn.m_url.path();
|
||||||
fn.m_data.append(str);
|
if (!path.isEmpty() && !path.endsWith(QLatin1Char('/')))
|
||||||
|
path.append('/');
|
||||||
|
fn.m_url.setPath(path);
|
||||||
|
} else {
|
||||||
|
if (!fn.m_data.isEmpty() && !fn.m_data.endsWith(QLatin1Char('/')))
|
||||||
|
fn.m_data.append('/');
|
||||||
|
fn.m_data.append(str);
|
||||||
|
}
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1173,6 +1327,7 @@ void withNtfsPermissions(const std::function<void()> &task)
|
|||||||
qt_ntfs_permission_lookup--;
|
qt_ntfs_permission_lookup--;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
std::hash<Utils::FilePath>::result_type
|
std::hash<Utils::FilePath>::result_type
|
||||||
|
@@ -66,6 +66,18 @@ class tst_fileutils;
|
|||||||
|
|
||||||
namespace Utils {
|
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 &)> createDir;
|
||||||
|
std::function<QList<FilePath>(const FilePath &, const QStringList &, QDir::Filters)> dirEntries;
|
||||||
|
std::function<QByteArray(const FilePath &, int)> fileContents;
|
||||||
|
};
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT FilePath
|
class QTCREATOR_UTILS_EXPORT FilePath
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -79,6 +91,8 @@ public:
|
|||||||
static FilePath fromVariant(const QVariant &variant);
|
static FilePath fromVariant(const QVariant &variant);
|
||||||
|
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
FilePath onDevice(const FilePath &deviceTemplate) const;
|
||||||
|
|
||||||
QFileInfo toFileInfo() const;
|
QFileInfo toFileInfo() const;
|
||||||
QVariant toVariant() const;
|
QVariant toVariant() const;
|
||||||
QDir toDir() const;
|
QDir toDir() const;
|
||||||
@@ -88,8 +102,20 @@ public:
|
|||||||
|
|
||||||
QString fileName() const;
|
QString fileName() const;
|
||||||
QString fileNameWithPathComponents(int pathComponents) const;
|
QString fileNameWithPathComponents(int pathComponents) const;
|
||||||
|
QString path() const;
|
||||||
|
|
||||||
|
bool needsDevice() const;
|
||||||
bool exists() const;
|
bool exists() const;
|
||||||
bool isWritablePath() const;
|
|
||||||
|
bool isWritablePath() const { return isWritableDir(); } // Remove.
|
||||||
|
bool isWritableDir() const;
|
||||||
|
bool isExecutableFile() const;
|
||||||
|
bool isReadableFile() const;
|
||||||
|
bool isReadableDir() const;
|
||||||
|
bool createDir() const;
|
||||||
|
QList<FilePath> dirEntries(const QStringList &nameFilters, QDir::Filters filters) const;
|
||||||
|
QList<FilePath> dirEntries(QDir::Filters filters) const;
|
||||||
|
QByteArray fileContents(int maxSize = -1) const;
|
||||||
|
|
||||||
FilePath parentDir() const;
|
FilePath parentDir() const;
|
||||||
FilePath absolutePath() const;
|
FilePath absolutePath() const;
|
||||||
@@ -116,21 +142,24 @@ public:
|
|||||||
FilePath pathAppended(const QString &str) const;
|
FilePath pathAppended(const QString &str) const;
|
||||||
FilePath stringAppended(const QString &str) const;
|
FilePath stringAppended(const QString &str) const;
|
||||||
FilePath resolvePath(const QString &fileName) const;
|
FilePath resolvePath(const QString &fileName) const;
|
||||||
|
FilePath resolveSymlinkTarget() const;
|
||||||
|
|
||||||
FilePath canonicalPath() const;
|
FilePath canonicalPath() const;
|
||||||
|
|
||||||
FilePath operator/(const QString &str) const;
|
FilePath operator/(const QString &str) const;
|
||||||
|
|
||||||
void clear() { m_data.clear(); }
|
void clear();
|
||||||
bool isEmpty() const { return m_data.isEmpty(); }
|
bool isEmpty() const;
|
||||||
|
|
||||||
uint hash(uint seed) const;
|
uint hash(uint seed) const;
|
||||||
|
|
||||||
// NOTE: FilePath operations on FilePath created from URL currenly
|
// NOTE: Most FilePath operations on FilePath created from URL currently
|
||||||
// do not work except for .toVariant() and .toUrl().
|
// do not work. Among the working are .toVariant() and .toUrl().
|
||||||
static FilePath fromUrl(const QUrl &url);
|
static FilePath fromUrl(const QUrl &url);
|
||||||
QUrl toUrl() const;
|
QUrl toUrl() const;
|
||||||
|
|
||||||
|
static void setDeviceFileHooks(const DeviceFileHooks &hooks);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ::tst_fileutils;
|
friend class ::tst_fileutils;
|
||||||
static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath);
|
static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath);
|
||||||
|
Reference in New Issue
Block a user