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 {
|
||||
|
||||
static DeviceFileHooks s_deviceHooks;
|
||||
|
||||
/*! \class Utils::CommandLine
|
||||
|
||||
\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);
|
||||
}
|
||||
|
||||
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
|
||||
absolute path is given.
|
||||
@@ -421,6 +434,13 @@ FilePath FilePath::resolvePath(const QString &fileName) const
|
||||
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 newCommonPath = oldCommonPath;
|
||||
@@ -737,6 +757,11 @@ QUrl FilePath::toUrl() const
|
||||
return m_url;
|
||||
}
|
||||
|
||||
void FilePath::setDeviceFileHooks(const DeviceFileHooks &hooks)
|
||||
{
|
||||
s_deviceHooks = hooks;
|
||||
}
|
||||
|
||||
/// \returns a QString to display to the user
|
||||
/// Converts the separators to the native format
|
||||
QString FilePath::toUserOutput() const
|
||||
@@ -777,20 +802,117 @@ QString FilePath::fileNameWithPathComponents(int pathComponents) const
|
||||
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
|
||||
/// FilePath exists.
|
||||
bool FilePath::exists() const
|
||||
{
|
||||
QTC_ASSERT(!needsDevice(), return false);
|
||||
return !isEmpty() && QFileInfo::exists(m_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \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};
|
||||
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.
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
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 fn = *this;
|
||||
if (str.isEmpty())
|
||||
return fn;
|
||||
if (!isEmpty() && !m_data.endsWith(QLatin1Char('/')))
|
||||
fn.m_data.append('/');
|
||||
fn.m_data.append(str);
|
||||
if (fn.m_url.isValid()) {
|
||||
QString path = fn.m_url.path();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1173,6 +1327,7 @@ void withNtfsPermissions(const std::function<void()> &task)
|
||||
qt_ntfs_permission_lookup--;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
std::hash<Utils::FilePath>::result_type
|
||||
|
@@ -66,6 +66,18 @@ class tst_fileutils;
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@@ -79,6 +91,8 @@ public:
|
||||
static FilePath fromVariant(const QVariant &variant);
|
||||
|
||||
QString toString() const;
|
||||
FilePath onDevice(const FilePath &deviceTemplate) const;
|
||||
|
||||
QFileInfo toFileInfo() const;
|
||||
QVariant toVariant() const;
|
||||
QDir toDir() const;
|
||||
@@ -88,8 +102,20 @@ public:
|
||||
|
||||
QString fileName() const;
|
||||
QString fileNameWithPathComponents(int pathComponents) const;
|
||||
QString path() const;
|
||||
|
||||
bool needsDevice() 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 absolutePath() const;
|
||||
@@ -116,21 +142,24 @@ public:
|
||||
FilePath pathAppended(const QString &str) const;
|
||||
FilePath stringAppended(const QString &str) const;
|
||||
FilePath resolvePath(const QString &fileName) const;
|
||||
FilePath resolveSymlinkTarget() const;
|
||||
|
||||
FilePath canonicalPath() const;
|
||||
|
||||
FilePath operator/(const QString &str) const;
|
||||
|
||||
void clear() { m_data.clear(); }
|
||||
bool isEmpty() const { return m_data.isEmpty(); }
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
|
||||
uint hash(uint seed) const;
|
||||
|
||||
// NOTE: FilePath operations on FilePath created from URL currenly
|
||||
// do not work except for .toVariant() and .toUrl().
|
||||
// NOTE: Most FilePath operations on FilePath created from URL currently
|
||||
// do not work. Among the working are .toVariant() and .toUrl().
|
||||
static FilePath fromUrl(const QUrl &url);
|
||||
QUrl toUrl() const;
|
||||
|
||||
static void setDeviceFileHooks(const DeviceFileHooks &hooks);
|
||||
|
||||
private:
|
||||
friend class ::tst_fileutils;
|
||||
static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath);
|
||||
|
Reference in New Issue
Block a user