diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index edd06b5658c..a713292c142 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -311,21 +311,23 @@ TempFileSaver::~TempFileSaver() } /*! - \class Utils::FileUtils + \namespace Utils::FileUtils \inmodule QtCreator - \brief The FileUtils class contains file and directory related convenience + \brief The FileUtils namespace contains file and directory related convenience functions. */ +namespace FileUtils { #ifdef QT_GUI_LIB -FileUtils::CopyAskingForOverwrite::CopyAskingForOverwrite(QWidget *dialogParent, const std::function &postOperation) +CopyAskingForOverwrite::CopyAskingForOverwrite(QWidget *dialogParent, + const std::function &postOperation) : m_parent(dialogParent) , m_postOperation(postOperation) {} -FileUtils::CopyHelper FileUtils::CopyAskingForOverwrite::operator()() +CopyHelper CopyAskingForOverwrite::operator()() { CopyHelper helperFunction = [this](const FilePath &src, const FilePath &dest, QString *error) { bool copyFile = true; @@ -373,13 +375,13 @@ FileUtils::CopyHelper FileUtils::CopyAskingForOverwrite::operator()() return helperFunction; } -FilePaths FileUtils::CopyAskingForOverwrite::files() const +FilePaths CopyAskingForOverwrite::files() const { return m_files; } #endif // QT_GUI_LIB -FilePath FileUtils::commonPath(const FilePaths &paths) +FilePath commonPath(const FilePaths &paths) { if (paths.isEmpty()) return {}; @@ -425,17 +427,6 @@ FilePath FileUtils::commonPath(const FilePaths &paths) return result; } -#ifdef Q_OS_WIN -template <> -void withNtfsPermissions(const std::function &task) -{ - qt_ntfs_permission_lookup++; - task(); - qt_ntfs_permission_lookup--; -} -#endif - - #ifdef QT_WIDGETS_LIB static QUrl filePathToQUrl(const FilePath &filePath) @@ -511,7 +502,7 @@ FilePath firstOrEmpty(const FilePaths &filePaths) return filePaths.isEmpty() ? FilePath() : filePaths.first(); } -bool FileUtils::hasNativeFileDialog() +bool hasNativeFileDialog() { static std::optional hasNative; if (!hasNative.has_value()) { @@ -524,14 +515,14 @@ bool FileUtils::hasNativeFileDialog() return *hasNative; } -FilePath FileUtils::getOpenFilePath(QWidget *parent, - const QString &caption, - const FilePath &dir, - const QString &filter, - QString *selectedFilter, - QFileDialog::Options options, - bool fromDeviceIfShiftIsPressed, - bool forceNonNativeDialog) +FilePath getOpenFilePath(QWidget *parent, + const QString &caption, + const FilePath &dir, + const QString &filter, + QString *selectedFilter, + QFileDialog::Options options, + bool fromDeviceIfShiftIsPressed, + bool forceNonNativeDialog) { forceNonNativeDialog = forceNonNativeDialog || dir.needsDevice(); #ifdef QT_GUI_LIB @@ -553,13 +544,13 @@ FilePath FileUtils::getOpenFilePath(QWidget *parent, QFileDialog::AcceptOpen)); } -FilePath FileUtils::getSaveFilePath(QWidget *parent, - const QString &caption, - const FilePath &dir, - const QString &filter, - QString *selectedFilter, - QFileDialog::Options options, - bool forceNonNativeDialog) +FilePath getSaveFilePath(QWidget *parent, + const QString &caption, + const FilePath &dir, + const QString &filter, + QString *selectedFilter, + QFileDialog::Options options, + bool forceNonNativeDialog) { forceNonNativeDialog = forceNonNativeDialog || dir.needsDevice(); @@ -576,12 +567,12 @@ FilePath FileUtils::getSaveFilePath(QWidget *parent, QFileDialog::AcceptSave)); } -FilePath FileUtils::getExistingDirectory(QWidget *parent, - const QString &caption, - const FilePath &dir, - QFileDialog::Options options, - bool fromDeviceIfShiftIsPressed, - bool forceNonNativeDialog) +FilePath getExistingDirectory(QWidget *parent, + const QString &caption, + const FilePath &dir, + QFileDialog::Options options, + bool fromDeviceIfShiftIsPressed, + bool forceNonNativeDialog) { forceNonNativeDialog = forceNonNativeDialog || dir.needsDevice(); @@ -604,12 +595,12 @@ FilePath FileUtils::getExistingDirectory(QWidget *parent, QFileDialog::AcceptOpen)); } -FilePaths FileUtils::getOpenFilePaths(QWidget *parent, - const QString &caption, - const FilePath &dir, - const QString &filter, - QString *selectedFilter, - QFileDialog::Options options) +FilePaths getOpenFilePaths(QWidget *parent, + const QString &caption, + const FilePath &dir, + const QString &filter, + QString *selectedFilter, + QFileDialog::Options options) { bool forceNonNativeDialog = dir.needsDevice(); @@ -704,7 +695,7 @@ FilePathInfo::FileFlags fileInfoFlagsfromStatMode(const QString &hexString, int return result; } -FilePathInfo FileUtils::filePathInfoFromTriple(const QString &infos, int modeBase) +FilePathInfo filePathInfoFromTriple(const QString &infos, int modeBase) { const QStringList parts = infos.split(' ', Qt::SkipEmptyParts); if (parts.size() != 3) @@ -717,10 +708,10 @@ FilePathInfo FileUtils::filePathInfoFromTriple(const QString &infos, int modeBas return {size, flags, dt}; } -bool FileUtils::copyRecursively(const FilePath &srcFilePath, - const FilePath &tgtFilePath, - QString *error, - CopyHelper copyHelper) +bool copyRecursively(const FilePath &srcFilePath, + const FilePath &tgtFilePath, + QString *error, + CopyHelper copyHelper) { if (srcFilePath.isDir()) { if (!tgtFilePath.ensureWritableDir()) { @@ -753,7 +744,7 @@ bool FileUtils::copyRecursively(const FilePath &srcFilePath, Returns whether the operation succeeded. */ -Result FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath) +Result copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath) { if (!srcFilePath.exists()) return Result::Error(Tr::tr("File %1 does not exist.").arg(srcFilePath.toUserOutput())); @@ -779,7 +770,7 @@ Result FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &t return srcFilePath.copyFile(tgtFilePath); } -QString FileUtils::fileSystemFriendlyName(const QString &name) +QString fileSystemFriendlyName(const QString &name) { QString result = name; static const QRegularExpression nonWordEx("\\W"); @@ -795,13 +786,13 @@ QString FileUtils::fileSystemFriendlyName(const QString &name) return result; } -int FileUtils::indexOfQmakeUnfriendly(const QString &name, int startpos) +int 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 qmakeFriendlyName(const QString &name) { QString result = name; @@ -814,14 +805,14 @@ QString FileUtils::qmakeFriendlyName(const QString &name) return fileSystemFriendlyName(result); } -bool FileUtils::makeWritable(const FilePath &path) +bool 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) +QString normalizedPathName(const QString &name) { #ifdef Q_OS_WIN const QString nativeSeparatorName(QDir::toNativeSeparators(name)); @@ -842,7 +833,7 @@ QString FileUtils::normalizedPathName(const QString &name) #endif } -FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &filePath) +FilePath commonPath(const FilePath &oldCommonPath, const FilePath &filePath) { FilePath newCommonPath = oldCommonPath; while (!newCommonPath.isEmpty() && !filePath.isChildOf(newCommonPath)) @@ -850,12 +841,12 @@ FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &fi return newCommonPath.canonicalPath(); } -FilePath FileUtils::homePath() +FilePath homePath() { return FilePath::fromUserInput(QDir::homePath()); } -expected_str FileUtils::scratchBufferFilePath(const QString &pattern) +expected_str scratchBufferFilePath(const QString &pattern) { QString tmp = pattern; QFileInfo fi(tmp); @@ -876,12 +867,12 @@ expected_str FileUtils::scratchBufferFilePath(const QString &pattern) return FilePath::fromString(file.fileName()); } -FilePaths FileUtils::toFilePathList(const QStringList &paths) +FilePaths toFilePathList(const QStringList &paths) { return transform(paths, &FilePath::fromString); } -qint64 FileUtils::bytesAvailableFromDFOutput(const QByteArray &dfOutput) +qint64 bytesAvailableFromDFOutput(const QByteArray &dfOutput) { const auto lines = filtered(dfOutput.split('\n'), [](const QByteArray &line) { return line.size() > 0; }); @@ -903,7 +894,7 @@ qint64 FileUtils::bytesAvailableFromDFOutput(const QByteArray &dfOutput) return -1; } -FilePaths FileUtils::usefulExtraSearchPaths() +FilePaths usefulExtraSearchPaths() { if (HostOsInfo::isMacHost()) { return {"/opt/homebrew/bin"}; @@ -917,4 +908,16 @@ FilePaths FileUtils::usefulExtraSearchPaths() return {}; } +} // namespace FileUtils + +#ifdef Q_OS_WIN +template <> +void withNtfsPermissions(const std::function &task) +{ + qt_ntfs_permission_lookup++; + task(); + qt_ntfs_permission_lookup--; +} +#endif + } // namespace Utils diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index d78dbb03ffa..a894d33a403 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -21,7 +21,6 @@ QT_BEGIN_NAMESPACE class QDataStream; class QTextStream; -class QWidget; class QXmlStreamWriter; // for withNtfsPermissions @@ -31,94 +30,95 @@ extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; QT_END_NAMESPACE namespace Utils { +namespace FileUtils { -class CommandLine; - -class QTCREATOR_UTILS_EXPORT FileUtils +using CopyHelper = std::function; +#ifdef QT_GUI_LIB +class QTCREATOR_UTILS_EXPORT CopyAskingForOverwrite { public: - using CopyHelper = std::function; -#ifdef QT_GUI_LIB - class QTCREATOR_UTILS_EXPORT CopyAskingForOverwrite - { - public: - CopyAskingForOverwrite(QWidget *dialogParent, - const std::function &postOperation = {}); - CopyHelper operator()(); - FilePaths files() const; + CopyAskingForOverwrite(QWidget *dialogParent, + const std::function &postOperation = {}); + CopyHelper operator()(); + FilePaths files() const; - private: - QWidget *m_parent; - FilePaths m_files; - std::function m_postOperation; - bool m_overwriteAll = false; - bool m_skipAll = false; - }; +private: + QWidget *m_parent; + FilePaths m_files; + std::function m_postOperation; + bool m_overwriteAll = false; + bool m_skipAll = false; +}; #endif // QT_GUI_LIB - static bool copyRecursively( - const FilePath &srcFilePath, - const FilePath &tgtFilePath, - QString *error, - CopyHelper helper); +QTCREATOR_UTILS_EXPORT bool copyRecursively( + const FilePath &srcFilePath, + const FilePath &tgtFilePath, + QString *error, + CopyHelper helper); - static Result copyIfDifferent(const FilePath &srcFilePath, - const FilePath &tgtFilePath); - static QString fileSystemFriendlyName(const QString &name); - static int indexOfQmakeUnfriendly(const QString &name, int startpos = 0); - static QString qmakeFriendlyName(const QString &name); - static bool makeWritable(const FilePath &path); - static QString normalizedPathName(const QString &name); +QTCREATOR_UTILS_EXPORT Result copyIfDifferent(const FilePath &srcFilePath, + const FilePath &tgtFilePath); +QTCREATOR_UTILS_EXPORT QString fileSystemFriendlyName(const QString &name); +QTCREATOR_UTILS_EXPORT int indexOfQmakeUnfriendly(const QString &name, int startpos = 0); +QTCREATOR_UTILS_EXPORT QString qmakeFriendlyName(const QString &name); +QTCREATOR_UTILS_EXPORT bool makeWritable(const FilePath &path); +QTCREATOR_UTILS_EXPORT QString normalizedPathName(const QString &name); - static FilePath commonPath(const FilePath &oldCommonPath, const FilePath &fileName); - static FilePath commonPath(const FilePaths &paths); - static FilePath homePath(); - static expected_str scratchBufferFilePath(const QString &pattern); +QTCREATOR_UTILS_EXPORT FilePath commonPath(const FilePath &oldCommonPath, const FilePath &fileName); +QTCREATOR_UTILS_EXPORT FilePath commonPath(const FilePaths &paths); +QTCREATOR_UTILS_EXPORT FilePath homePath(); +QTCREATOR_UTILS_EXPORT expected_str scratchBufferFilePath(const QString &pattern); - static FilePaths toFilePathList(const QStringList &paths); +QTCREATOR_UTILS_EXPORT FilePaths toFilePathList(const QStringList &paths); - static qint64 bytesAvailableFromDFOutput(const QByteArray &dfOutput); +QTCREATOR_UTILS_EXPORT qint64 bytesAvailableFromDFOutput(const QByteArray &dfOutput); - static FilePathInfo filePathInfoFromTriple(const QString &infos, int modeBase); +QTCREATOR_UTILS_EXPORT FilePathInfo filePathInfoFromTriple(const QString &infos, int modeBase); - //! Returns known paths like /opt/homebrew on macOS that might not be in PATH - static FilePaths usefulExtraSearchPaths(); +//! Returns known paths like /opt/homebrew on macOS that might not be in PATH +QTCREATOR_UTILS_EXPORT FilePaths usefulExtraSearchPaths(); #ifdef QT_WIDGETS_LIB - static bool hasNativeFileDialog(); +QTCREATOR_UTILS_EXPORT bool hasNativeFileDialog(); - static FilePath getOpenFilePath(QWidget *parent, - const QString &caption, - const FilePath &dir = {}, - const QString &filter = {}, - QString *selectedFilter = nullptr, - QFileDialog::Options options = {}, - bool fromDeviceIfShiftIsPressed = false, - bool forceNonNativeDialog = false); +QTCREATOR_UTILS_EXPORT FilePath getOpenFilePath( + QWidget *parent, + const QString &caption, + const FilePath &dir = {}, + const QString &filter = {}, + QString *selectedFilter = nullptr, + QFileDialog::Options options = {}, + bool fromDeviceIfShiftIsPressed = false, + bool forceNonNativeDialog = false); - static FilePath getSaveFilePath(QWidget *parent, - const QString &caption, - const FilePath &dir = {}, - const QString &filter = {}, - QString *selectedFilter = nullptr, - QFileDialog::Options options = {}, - bool forceNonNativeDialog = false); +QTCREATOR_UTILS_EXPORT FilePath getSaveFilePath( + QWidget *parent, + const QString &caption, + const FilePath &dir = {}, + const QString &filter = {}, + QString *selectedFilter = nullptr, + QFileDialog::Options options = {}, + bool forceNonNativeDialog = false); - static FilePath getExistingDirectory(QWidget *parent, - const QString &caption, - const FilePath &dir = {}, - QFileDialog::Options options = QFileDialog::ShowDirsOnly, - bool fromDeviceIfShiftIsPressed = false, - bool forceNonNativeDialog = false); +QTCREATOR_UTILS_EXPORT FilePath getExistingDirectory( + QWidget *parent, + const QString &caption, + const FilePath &dir = {}, + QFileDialog::Options options = QFileDialog::ShowDirsOnly, + bool fromDeviceIfShiftIsPressed = false, + bool forceNonNativeDialog = false); - static FilePaths getOpenFilePaths(QWidget *parent, - const QString &caption, - const FilePath &dir = {}, - const QString &filter = {}, - QString *selectedFilter = nullptr, - QFileDialog::Options options = {}); +QTCREATOR_UTILS_EXPORT FilePaths getOpenFilePaths( + QWidget *parent, + const QString &caption, + const FilePath &dir = {}, + const QString &filter = {}, + QString *selectedFilter = nullptr, + QFileDialog::Options options = {}); #endif -}; + +} // namespace FileUtils // for actually finding out if e.g. directories are writable on Windows #ifdef Q_OS_WIN